Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Bean Manipulation Using Dozer Framework

DZone's Guide to

Bean Manipulation Using Dozer Framework

· Java Zone
Free Resource

Check out this 8-step guide to see how you can increase your productivity by skipping slow application redeploys and by implementing application profiling, as you code! Brought to you in partnership with ZeroTurnaround.

Introduction

As you know you can copy file or folder from source location to destination location in any operating system. Have you ever thought about copy the java object which is basically a POJO ? There are many instances where you need to copy the source bean contents to a destination bean. I am not taking about the copy constructor, shallow or deep copy or clone of an object. In some circumstances you have to copy the contents of the source bean to a destination with or without filter conditions. There can be n number of reasons to do this and there are many ways you can achieve it. In this small post I will provide you a glimpse of a framework called “Dozer” to achieve this functionality in an easiest and robust manner.

Technicalities

This small article will provide you the utility of “Dozer” framework to copy a source bean to a destination bean. Before we start, let us think about a situation that you have a source bean which contains lot of fields and the source bean belongs to a different project or module. Now you want to expose the bean to the outside world as a part of your web service REST service development. It is not advisable to do it. There may be the following reasons.

  • The source system does not allow doing it because of security breach.
  • The source bean is not serialized and a final class.
  • The source bean has lot of fields; some of them are not required.
  • The source bean is very heavy and contains lot of nested beans.
  • The source bean has fields of different types which may not be required for other system.

The above may be some other specific reasons, think about a situation, you want to make a REST call or web service call to get the minimal account details of a person. But the source system has a bean called “AccountBean” which contains many sensitive information like person’s internet banking password, profile password, pan no or social security number, total balance etc. You want to develop an application where you want to expose only account’s address details, name and home branch of the bank. This is a required situation where you want to have your custom defined bean which should be exposed to outside based upon the account number. In this case you have to copy the original bean to your custom defined bean. To achieve this functionality you can do it in the following ways.

  • Write code to manually copy the contents of the source bean to destination bean.
  • Use java Reflection or Introspection utility to copy from source to destination bean.
  • Use an available framework which does the copy automatically.

In this case we will learn about a framework which helps us to copy the contents of a source bean to destination bean. The framework called “Dozer” is very popular and flexible to use and integrate in the application. You will find more documentation on Dozer in various internet sites. In this post I will provide you very basic and practical usage of Dozer.

  Let’s quickly learn the usage of Dozer in the following scenarios.

  • Copy source Plain/Flat bean to destination Plain/Flat bean
  • Copy collections
  • Bi-directional bean copy
  • Copy flat bean to nested bean and vice versa
  • Copy bean with custom conversion.

Copy source Plain/Flat bean to destination Plain/Flat bean

This is the simplest case where we have a source POJO and we want to copy into destination POJO. Let us consider the following java code.

Structure of source POJO below.

package com.ddlab.rnd.type1.srcpkg;

/**
 * The Class Person is used as a source bean for Person which contains Address
 * object.
 * 
 * @author <a href="mailto:debadatta.mishra@gmail.com">Debadatta Mishra</a>
 * @since 2013
 */
public class Person {

/** The name. */
private String name;

/** The age. */
private int age;

/** The adrs. */
private Address adrs;

// All getter and setter method below
}

Structure of destination POJO below.

package com.ddlab.rnd.type1.destnpkg;

/**
 * The Class Person1 is used as destination bean for Person1 which contains
 * Addrss1 object
 * 
 * @author <a href="mailto:debadatta.mishra@gmail.com">Debadatta Mishra</a>
 * @since 2013
 */
public class Person1 {

/** The name1. */
private String name1;

/** The age1. */
private int age1;

/** The adrs1. */
private Address1 adrs1;

//All getter setter method below
}

Let us see the dozer mapping file called “dozerMapping.xml”

<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozer.sourceforge.net" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://dozer.sourceforge.net http://dozer.sourceforge.net/schema/beanmapping.xsd">

<mapping map-id="a">
<class-a>com.ddlab.rnd.type1.srcpkg.Person</class-a>
<class-b>com.ddlab.rnd.type1.destnpkg.Person1</class-b>
<field>
<a>name</a>
<b>name1</b>
</field>
<field>
<a>age</a>
<b>age1</b>
</field>
<field>
<a>adrs.doorNo</a>
<b>adrs1.doorNo1</b>
</field>
<field>
<a>adrs.stName</a>
<b>adrs1.stName1</b>
</field>
</mapping>
</mappings>

The above xml configuration file looks very intuitive as <class-a > refers to source bean and < class-b> refers to destination bean. The other field <a> refers to the property of source bean and <b> refers to the property of the destination bean.

Let us see the final code which does the bean mapping.

List<String> list = new ArrayList<String>();
// Add the mapping configuration
list.add("dozerMapping.xml");
// Add to DozerMapper
Mapper mapper = new DozerBeanMapper(list);
mapper.map(p, p1, "a");

Now it is done, it looks very simple and provides many powerful features. You have remember the following few things for bean copy using “Dozer” framework.

  • Source bean
  • Destination bean
  • Dozer mapping file configuration
  • Mapping configuration should contain source POJO class with proper package name
  • Mapping configuration should contain destination POJO class with proper package name
  • Mapping configuration should have proper exact property name what you have defined in the java class

The mapping configuration provides the following benefits.

  • You can change the property name as and when required and it does not require to build the application.
  • You can add the property in the java class as and when required.
  • You can have one or many property files for specific requirements.
  • You can edit and remove the mapping as and when required.
  • You can also configure the mapping in Spring application ie spring configuration file.

Copy collections

There are certain occasions where you want to copy list of source type to list of destination type. The list may contain different types of objects. Let us see a typical java code below.

package com.ddlab.dozer.type2.srcpkg;
import java.util.List;

/**
 * The Class AddressList is used as a source List object which contains object
 * of type Address.
 * 
 * @author <a href="mailto:debadatta.mishra@gmail.com">Debadatta Mishra</a>
 * @since 2013
 */
public class AddressList {

/** The adrs list. */
private List<Address> adrsList;

/**
 * Gets the adrs list.
 * 
 * @return the adrs list
 */
public List<Address> getAdrsList() {
return adrsList;
}

/**
 * Sets the adrs list.
 * 
 * @param adrsList
 *            the new adrs list
 */
public void setAdrsList(List<Address> adrsList) {
this.adrsList = adrsList;
}

}

In the above case the list contains list of Address type objects. Let us learn how to achieve.

First of all create a mapping between Address objects from source to destination and then create a mapping between source list to destination list. Let us see the mapping configuration file.

<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozer.sourceforge.net"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://dozer.sourceforge.net http://dozer.sourceforge.net/schema/beanmapping.xsd">

      <mapping map-id="k">
<class-a>com.ddlab.dozer.type2.srcpkg.Address</class-a>
<class-b>com.ddlab.dozer.type2.destnpkg.AddressBean</class-b>
<field>
<a>name</a>
<b>name</b>
</field>
<field >
<a>id</a>
<b>id</b>
</field>
</mapping>

<mapping map-id="q1" type="one-way" relationship-type="non-cumulative">
<class-a>com.ddlab.dozer.type2.srcpkg.AddressList</class-a>
<class-b>com.ddlab.dozer.type2.destnpkg.AddressBeanList</class-b>

<field map-id="k">
<a>adrsList</a>
<b>adrsList</b>
</field>
</mapping>

</mappings>

To copy the list object, you can use the same code which is in the first case.

Bi-directional bean copy

In this case you need to have a mapping which does bean copy in both the direction. Let us think about a situation where you want to convert the internal java bean to a custom bean to expose as web service and finally you receive the data in the custom bean and convert it into internal bean. It is not advisable to write another mapping. “Dozer” provides attributes in the xml mapping configuration to copy in both the direction based upon the requirement. I provide the attribute required to mention in dozer configuration.

<mapping map-id="k" type="bi-directional">
<!-- Other field mapping -->
</mapping>

The above attribute type (BOLD) provides the flexibility of copying objects in both direction.

Copy flat bean to nested bean and vice versa

Based upon the project requirement, you may have a complex bean which contains nested other java beans. You may have to copy the complex bean to a simple type  or vice versa. Let us see the mapping configuration.

<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozer.sourceforge.net"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://dozer.sourceforge.net http://dozer.sourceforge.net/schema/beanmapping.xsd">

      <mapping map-id="a">
<class-a>com.ddlab.dozer.type4.srcpkg.MyPerson</class-a>
<class-b>com.ddlab.dozer.type4.destnpkg.Person1</class-b>
<!-- Other field info -->
<field>
 <a>doorNo</a>
<b>adrs1.doorNo1</b>
</field>
<field>
<a>stName</a>
<b>adrs1.stName1</b>
</field>
<field>
<a>cname</a>
<b>adrs1.country.name</b>
</field>
<field>
<a>ccode</a>
<b>adrs1.country.code</b>
</field>
<field>
<a>fd</a>
<b>adrs1.country.bd</b>
</field>
</mapping>
</mappings>

In the above case mark the line in red colour. To have a hands-on example, refer to the following mapping configuration file.

flat2NestedBeanMapping.xml

nestedBeanMapping2Flat.xml

Refer to the following packages for this.

com.ddlab.dozer.type4.destnpkg

com.ddlab.dozer.type4.srcpkg

You can download the complete eclipse project from the following link.

https://www.dropbox.com/s/j6ep7wq7lalfe2k/dozerbeancopy.zip

Copy bean with custom conversion.

This is a very typical and a complex condition which occurs during the time of development. Imagine that you have java bean which contains specific fields like date in JodaTime api, object of type UUID, field of type BigInteger etc and you have a java bean with all primitive type fields. In this case you have to use custom converters and inject in “Dozer” mapping configuration file so that “Dozer” will automatically copy the java bean with proper field types.

Let us see the structure of the mapping file.

<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozer.sourceforge.net" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://dozer.sourceforge.net http://dozer.sourceforge.net/schema/beanmapping.xsd">

<configuration>
<custom-converters>
<converter type="com.ddlab.dozer.type5.converters.Date2JodaDateConverter">
<class-a>org.joda.time.LocalDate</class-a>
<class-b>java.util.Date</class-b>
</converter>
</custom-converters>
</configuration>

<mapping map-id="k" type="bi-directional">
<class-a>com.ddlab.dozer.type5.srcpkg.SrcBean</class-a>
<class-b>com.ddlab.dozer.type5.destnpkg.DestnBean</class-b>

<!-- For UUID -->
<field copy-by-reference="true">
<a>idKey</a>
<b>uid</b>
</field>

<!-- For java.util.Date to org.joda.time.LocalDate -->
<field>
<a>utilDate</a>
<b>jodaDate</b>
</field>

<!--  For double to java.math.BigDecimal -->
<field>
<a>amount</a>
<b>bigDecimal</b>
</field>
</mapping>
</mappings>

Dozer provides an interface called “org.dozer.CustomConverter” which enables to do custom conversion based upon our requirements. I provide below a small code snippet.

package com.ddlab.dozer.type5.converters;

import org.dozer.CustomConverter;
import org.dozer.MappingException;
import org.joda.time.LocalDate;

/**
 * The Class Date2JodaDateConverter is used as a Dozer custom converter for
 * converting java.util.Date to Jodatime LocalDate.
 * 
 * @author <a href="mailto:debadatta.mishra@gmail.com">Debadatta Mishra</a>
 * @since 2013
 */
public class Date2JodaDateConverter implements CustomConverter {

/*
 * (non-Javadoc)
 * 
 * @see org.dozer.CustomConverter#convert(java.lang.Object,
 * java.lang.Object, java.lang.Class, java.lang.Class)
 */
@Override
public Object convert(Object existingDestinationFieldValue,
Object sourceFieldValue,
@SuppressWarnings("rawtypes") Class destinationClass,
@SuppressWarnings("rawtypes") Class sourceClass) {
if (sourceFieldValue == null) {
return null;
}

if (sourceFieldValue instanceof java.util.Date) {
java.util.Date utilDate = (java.util.Date) sourceFieldValue;
LocalDate localDate = new LocalDate(utilDate.getTime());
return localDate;
}
throw new MappingException("Misconfigured/unsupported mapping");
}

}

To know more about refer to the following packages.

com.ddlab.dozer.type5.converters

com.ddlab.dozer.type5.destnpkg

com.ddlab.dozer.type5.srcpkg

How to Do

To work with “Dozer” framework, you have to use the following jar files in your classpath.

commons-beanutils-1.7.jar

commons-lang-2.4.jar

commons-logging-1.1.1.jar

commons-logging-api-1.1.1.jar

dozer-5.3.2.jar

joda-time-2.2.jar

log4j-1.2.16.jar

log4j-over-slf4j-1.6.1.jar

slf4j-api-1.6.1.jar

slf4j-jdk14-1.6.1.jar

slf4j-simple-1.6.1.jar

You have to download “Dozer” framework from the following links.

http://dozer.sourceforge.net/ . Dozer also provides eclipse plugin to ease the work of mapping.

Related Packages and Configuration File

Plain bean to Plain Bean

com.ddlab.rnd.type1.destnpkg  (from src)

com.ddlab.rnd.type1.srcpkg  (from src)

com.ddlab.rnd.type1 (from test)

dozerMapping.xml (Mapping Configuration)

Collections Copy

com.ddlab.dozer.type2.destnpkg  (from src)

com.ddlab.dozer.type2.srcpkg  (from src)

com.ddlab.dozer.type2 (from test)

list2ListMapping.xml (Mapping Configuration)

Bi-directional Bean copy

com.ddlab.dozer.type3 (from test)

dozerBidirectionalMapping1.xml (Mapping Configuration)

Flat to Nested Bean/Nested Bean to Flat Bean

com.ddlab.dozer.type4.destnpkg  (from src)

com.ddlab.dozer.type4.srcpkg  (from src)

com.ddlab.dozer.type4  (from test)

flat2NestedBeanMapping.xml (Mapping Configuration)

nestedBeanMapping2Flat.xml (Mapping Configuration)

Custom Converter

com.ddlab.dozer.type5.converters  (from src)

com.ddlab.dozer.type5.destnpkg  (from src)

com.ddlab.dozer.type5.srcpkg  (from src)

com.ddlab.dozer.type5 (from test)

dozercustomconvertermapping.xml

Download

You can download the complete eclipse project from the following dropbox site.

https://www.dropbox.com/s/j6ep7wq7lalfe2k/dozerbeancopy.zip. You can easily configure the Eclipse IDE easily by importing the project.

Conclusion

I hope you have enjoyed my small post about the usage of Dozer framework for bean copy in java. Download the complete project and go through the source code to understand the concept and its usage. Based upon the complexity and design , you can decide whether to use this concept. For any kind of issues and error you can contact me at debadatta.mishra@gmail.com .

Resources and References

There are other frameworks also available provide bean manipulation in a more or less way. I found “Dozer” framework suitable in various grounds. There is also similar kind of framework called “Nomin” which provides mapping similar to that of “Dozer” by providing configuration in a properties file. I provide below the various links for your references.

http://dozer.sourceforge.net/documentation/gettingstarted.html

http://nomin.sourceforge.net/

http://modelmapper.org/

http://code.google.com/p/orika/

http://morph.sourceforge.net/

https://code.google.com/p/omapper/

The Java Zone is brought to you in partnership with ZeroTurnaround. Check out this 8-step guide to see how you can increase your productivity by skipping slow application redeploys and by implementing application profiling, as you code!

Topics:
java ,bean ,dozer

Published at DZone with permission of Debadatta Mishra. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}