Introduction
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 is mainly used when your model in UI is different from the JPA Entities. Dozer sits between UI model and JPA Entities and maps UI data into entities or vice versa.
In this example, I am going to cover the basics of dozer configuration and custom dozer converter which helps to map data for exceptional scenarios when a simple way can not be used. Spring is used to run this stand alone application.
Required Software
- Eclipse
- JDK 1.7 or above
- Maven 2.2.x or above
Steps to write code
The project structure and important files are shown below
SL No | File Name | Description |
---|---|---|
1 | com.config.DozerConfig | This is the spring annotation based configuration file which loads the dozer mapping file. |
2 | com.business.MapDozerImpl | This class has business logic to map values from source to destination |
3 | com.dozerbean.* | Lets assume the classes inside this package represents UI models in any real time project. ParentBean has the details of parents and Child bean has the details of child and included into parent bean as a list |
4 | com.entity.* | Lets assume the classes inside this package represents JPA Entities in any real time project |
5 | com.custom.converter.ChildCustomConverter | custom dozer converter which helps to map data for exceptional scenarios when a simple way can not be used. In this scenario, we are copying mother id into the list of children. |
6 | Main | This is the entry point of this dozer mapper application. This class creates an ParentBean objects (lets assume it is a UI model in real time project) and calls doxer framework to map into entities. |
The purpose of this application is to copy from ParentBean to Parent object
- POM.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ashish.dozer</groupId>
<artifactId>DoZerMapper</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source />
<target />
</configuration>
</plugin>
</plugins>
</build>
<properties>
<spring.version>4.1.4.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.3.1</version>
</dependency>
<!-- Dozer dependency START -->
<dependency>
<groupId>net.sf.dozer</groupId>
<artifactId>dozer</artifactId>
<version>5.5.1</version>
</dependency>
<!-- Dozer dependency END -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics-runtime</artifactId>
<version>0.9.4</version>
</dependency>
</dependencies>
</project>
- DozerConfig.java: This is the spring annotation based configuration file which loads the dozer mapping file.
package com.config;
import java.util.Arrays;
import java.util.List;
import org.dozer.DozerBeanMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(value={"com.business"})
public class DozerConfig {
@Bean(name = "org.dozer.Mapper")
public DozerBeanMapper dozerBean() {
List mappingFiles = Arrays.asList(
"globalMapping.xml",
"dozerMapping.xml"
);
DozerBeanMapper dozerBean = new DozerBeanMapper();
dozerBean.setMappingFiles(mappingFiles);
return dozerBean;
}
}
</code></pre>
* **MapDozerImpl.java**: This class has business logic to map values from source to destination.
package com.business;
import org.dozer.DozerBeanMapper;
import org.dozer.Mapper;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.stereotype.Component;
import com.config.DozerConfig;
import com.dozerbean.ParentBean;
import com.entity.Parent;
@Component
public class MapDozerImpl implements MapDozer{
public void mapBean(ParentBean srcParent, Parent destParent) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DozerConfig.class);
Mapper dozerBeanMapper = (Mapper) context.getBean("org.dozer.Mapper", DozerBeanMapper.class);
dozerBeanMapper.map(srcParent, destParent, "parentChildMapping");
}
}
* **ChildCustomConverter.java**: custom dozer converter which helps to map data for exceptional scenarios when a simple way can not be used. In this scenario, we are copying mother id into the list of children.
package com.custom.converter;
import java.util.List;
import org.dozer.DozerConverter;
import org.dozer.Mapper;
import org.dozer.MapperAware;
import com.entity.Child;
public class ChildCustomConverter extends DozerConverter<Integer, List> implements MapperAware {
public ChildCustomConverter() {
super(Integer.class, List.class);
}
public ChildCustomConverter(Class prototypeA, Class prototypeB) {
super(prototypeA, prototypeB);
}
public void setMapper(Mapper arg0) {
// TODO Auto-generated method stub
}
@Override
public Integer convertFrom(List src, Integer dest) {
// TODO Auto-generated method stub
return null;
}
@Override
public List convertTo(Integer src, List dest) {
// TODO Auto-generated method stub
if(src != null && dest != null && dest.size() > 0) {
for(Object o : dest) {
if(o instanceof Child) {
Child c = (Child)o;
// c.setfId(src);
c.setmId(src);
}
}
}
return dest;
}
}
</code></pre>
* **Main.java**: This is the entry point of this dozer mapper application. This class creates an ParentBean objects (lets assume it is a UI model in real time project) and calls doxer framework to map into entities.
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.business.MapDozerImpl;
import com.config.DozerConfig;
import com.dozerbean.ChildBean;
import com.dozerbean.ParentBean;
import com.entity.Parent;
import com.google.gson.Gson;
public class Main {
public static void main(String args[]) {
Main main = new Main();
main.loadBean();
}
private static ParentBean getParentBean() {
ParentBean pb = new ParentBean();
pb.setfId(10);
pb.setmId(11);
pb.setmAge(40);
pb.setfAge(40);
pb.setfName("XYZ");
pb.setmName("ABC");
List childList = new ArrayList();
for(int i = 0; i < 3; i++) {
ChildBean c = new ChildBean();
c.setId(i + 1);
c.setfId(10);
c.setmId(11);
c.setName("MNO" + i);
c.setAge(12 + i);
childList.add(c);
}
pb.setChild(childList);
return pb;
}
public void loadBean() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DozerConfig.class);
MapDozerImpl app = context.getBean(MapDozerImpl.class);
ParentBean pb = getParentBean();
Gson gson = new Gson();
String json = gson.toJson(pb);
System.out.println("Input Parent Bean JSON: " + json);
Parent p = new Parent();
app.mapBean(pb, p);
System.out.println("Output Parent JSON: " + gson.toJson(p));
}
}
</code></pre>
* **com.dozerbean.*** and **com.entity.*** Refer the above image for the respective object structures and download the code to get details about these bean classes.