Dozer Mapping

Dozer is a Java Bean to Java Bean mapper that recursively copies data from one object to another. Typically, these Java Beans will be of different complex types.

Dozer supports simple property mapping, complex type mapping, bi-directional mapping, implicit-explicit mapping, as well as recursive mapping. This includes mapping collection attributes that also need mapping at the element level.

Dozer not only supports mapping between attribute names, but also automatically converting between types. Most conversion scenarios are supported out of the box, but Dozer also allows you to specify custom conversions via XML.
The mapper is used any time you need to take one type of Java Bean and map it to another type of Java Bean. Most field mapping can be done automatically by Dozer using reflection, but any custom mapping can be predescribed in XML format. Mapping is bi-directional so only one relationship between classes needs defining. If any property names on both objects are the same you do not even need to do any explicit property mapping for these fields.

Employee.java

package com.javavillage.beans;

public class Employee {
	private String empID;
	private String streetNumber;
	private String city;
	private String state;
	private String country;
	/**
	 * @return the empID
	 */
	public String getEmpID() {
		return empID;
	}
	/**
	 * @param empID the empID to set
	 */
	public void setEmpID(String empID) {
		this.empID = empID;
	}
	/**
	 * @return the streetNumber
	 */
	public String getStreetNumber() {
		return streetNumber;
	}
	/**
	 * @param streetNumber the streetNumber to set
	 */
	public void setStreetNumber(String streetNumber) {
		this.streetNumber = streetNumber;
	}
	/**
	 * @return the city
	 */
	public String getCity() {
		return city;
	}
	/**
	 * @param city the city to set
	 */
	public void setCity(String city) {
		this.city = city;
	}
	/**
	 * @return the state
	 */
	public String getState() {
		return state;
	}
	/**
	 * @param state the state to set
	 */
	public void setState(String state) {
		this.state = state;
	}
	/**
	 * @return the country
	 */
	public String getCountry() {
		return country;
	}
	/**
	 * @param country the country to set
	 */
	public void setCountry(String country) {
		this.country = country;
	}
	
}

Address.java
package com.javavillage.beans;

public class Address {
	private String streetNumber;
	private String city;
	private String state;
	private String country;
	
	/**
	 * @return the streetNumber
	 */
	public String getStreetNumber() {
		return streetNumber;
	}
	/**
	 * @param streetNumber the streetNumber to set
	 */
	public void setStreetNumber(String streetNumber) {
		this.streetNumber = streetNumber;
	}
	/**
	 * @return the city
	 */
	public String getCity() {
		return city;
	}
	/**
	 * @param city the city to set
	 */
	public void setCity(String city) {
		this.city = city;
	}
	/**
	 * @return the state
	 */
	public String getState() {
		return state;
	}
	/**
	 * @param state the state to set
	 */
	public void setState(String state) {
		this.state = state;
	}
	/**
	 * @return the country
	 */
	public String getCountry() {
		return country;
	}
	/**
	 * @param country the country to set
	 */
	public void setCountry(String country) {
		this.country = country;
	}

}

dozerMapping.xml:

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.

<?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.javavillage.beans.Employee</class-a>
		<class-b>com.javavillage.beans.Address</class-b>
		<field>
			<a>streetNumber</a>
			<b>streetNumber</b>
		</field>
		<field>
			<a>city</a>
			<b>city</b>
		</field>
		<field>
			<a>state</a>
			<b>state</b>
		</field>
		<field>
			<a>country</a>
			<b>country</b>
		</field>
	</mapping>
</mappings>

Maven entries for pom.xml
		<dependency>
			<groupId>net.sf.dozer</groupId>
			<artifactId>dozer</artifactId>
			<version>5.3.1</version>
		</dependency>

MainDozer.java
package com.javavillage.dozer;

import java.util.ArrayList;
import java.util.List;

import org.dozer.DozerBeanMapper;
import org.dozer.Mapper;

import com.javavillage.beans.Address;
import com.javavillage.beans.Employee;

public class MainDozer {
	public static void main(String args[]) {
		List<String> list = new ArrayListt<String>();
		// Add the mapping configuration
		list.add("dozerMapping.xml");
		// Add to DozerMapper
		Employee emp = new Employee();
		emp.setEmpID("54601");
		emp.setStreetNumber("7G");
		emp.setState("Maharasthra");
		emp.setCity("Pune");
		emp.setCountry("India");
		
		Address address = new Address();
		Mapper mapper = new DozerBeanMapper(list);
		mapper.map(emp, address);
		System.out.println("StreetNumber "+address.getStreetNumber());
		System.out.println("State: "+address.getState());
		System.out.println("City: "+address.getCity());
		System.out.println("Country: "+address.getCountry());

	}
}

Execute MainDozer

Execution of MainDozer

Note:

If any property names on both objects are the same you do not even need to do any explicit property mapping for these fields. So in dozerMapping.xml fields are not required because fields are same in two classes. comment this line list.add("dozerMapping.xml"); in MainDozer.java and try executing this.