This dozer example will cover following.

  • how to pass parameter to dozer custom converter
  • how to create a generic custom converter
  • how to write custom converter if data types of source and destination are same

In real world applications, For instance we might see need to convert data in source field state “Florida” to destination field value “FL”.
We show values in UI drop downs or Webservice response as full form text ( “Florida” for state ) but in system we store it as ‘FL’, which is short form of ‘Florida’, to facilitate easy handling/processing of data.
Lets see how we could address such requirement with dozer.

1. Create Source and destination POJO classes

We will create AddressType which is used by front end layer and Address domain which is used by service layer/backend layer.


// Source POJO - AddressType.java
public class AddressType {

	private String addrLine1;
	private String city;
	private String state;
	private int zipCode;
// Removed setter and getter emthods
}
// Destination POJO - Address.java
public class Address {

	private String addrLine1;
	private String city;
	private String state;
	private int zip5;
// Removed setter and getters 
}

2. Create Custom Converter With Parameter

Now we are required to address source and target flows as under

  • convert State field from Full String(‘Florida’) to code(‘FL’) in source => destination flow.
  • convert State field from Code ( ‘FL’) to full string (‘Florida’) ( in destination => source flow.

  • NOTE: Since source and destination have same data type for state field. We just can’t address the conversion with one converter. Because Dozer custom converters does not specify which flow is under execution during the conversion process. To avoid such issue, we can create 2 generic custom converters.
    
    // Custom converter for Source To Destination flow.
    public class StringToCodeConverter extends DozerConverter {
    
    	public StringToCodeConverter(){
    		super(String.class,String.class);
    	}
    
    
    	@Override
    	public String convertTo(String source, String destination) {
    		if(getParameter().equals("STATE")){
    			//In real world application, Fetch state code and display value map from cache and convert
    			if(source!=null && source.equals("Florida")){
    				return "FL";
    			}
    		}
    		return null;
    	}
    
    	@Override
    	public String convertFrom(String source, String destination) {
    		// TODO Auto-generated method stub
    		return convertTo(source,destination);
    	}
    
    }
    // Custom converter for Destination TO source flow.
    public class CodeToStringConverter extends DozerConverter {
    
    	public CodeToStringConverter(){
    		super(String.class,String.class);
    	}
    
    	@Override
    	public String convertTo(String source, String destination) {
    		if(getParameter().equals("STATE")){
    			//In real world application, Fetch state code and display value map from cache and convert
    			if(source!=null && source.equals("FL")){
    				return "Florida";
    			}
    		}
    		return null;
    	}
    
    	@Override
    	public String convertFrom(String source, String destination) {
    		// TODO Auto-generated method stub
    		return convertTo(source,destination);
    	}
    	
    }
    

    If you observe the above code, we are using getParameter() usage to check which kind of conversion is needd here. In our case, “STATE” conversion is needed. This approach allows us create generic/common Custom converter for all such needs by allowing us to pass the parameter during mapping. How to pass parameter can be seen in next mapping section.

    3. Create mapping and configure dozer custom converter parameter

    <?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 type="one-way">
    	<class-a>com.codesimplify.dozersamples.customconverter.AddressType</class-a>
    	<class-b>com.codesimplify.dozersamples.customconverter.Address</class-b>
    	<field custom-converter="com.codesimplify.dozersamples.customconverter.StringToCodeConverter"  custom-converter-param="STATE">
    		<a>state</a>
    		<b>state</b>
    	</field>	
    	</mapping>	
    	<mapping type="one-way">
    	<class-a>com.codesimplify.dozersamples.customconverter.Address</class-a>
    	<class-b>com.codesimplify.dozersamples.customconverter.AddressType</class-b>
    	<field custom-converter="com.codesimplify.dozersamples.customconverter.CodeToStringConverter" custom-converter-param="STATE">
    		<a>state</a>
    		<b>state</b>
    	</field>		
    	</mapping>  
    </mappings>

    In the above mapping we could observe following.

  • mapping type=”one-way” usage – Instructs Dozer to do one one-way mapping only.We added this to address different conversion requirement for state in source => destination flow and destination=>source flow.
  • custom-converter-param – Allows us to pass “STATE” as parameter to genetic custom converter. Without this parameter, we would need to write multiple custom converters to do similar work for other conversions like City, Gender etc
  • 4. Run Application

    This step involves initializing dozer mapper and usage of it.

    public class App_CustomConverter 
    {
        public static void main( String[] args )
        {
        	DozerBeanMapper mapper=new DozerBeanMapper();
        	List myMappingFiles = new ArrayList();
        	myMappingFiles.add("DozerMappings_customconverters.xml");
        	mapper.setMappingFiles(myMappingFiles);
        	
        	AddressType addrType=new AddressType();
        	addrType.setAddrLine1("121 Howard Lane");
        	addrType.setCity("Orlando");
    		addrType.setState("Florida");
    		addrType.setZipCode(32050);
    		addrType.setCreatedBy("venkat");
        	Address destAddr=mapper.map(addrType, Address.class);
        	// Convert Address Type to Address Domain
        	System.out.println("AddressType=>Address:"+destAddr.toString());
        	
        	//Convert Address domain to AddressType
        	AddressType destAddrType=mapper.map(destAddr, AddressType.class);
        	System.out.println("Address=>AddressType:"+destAddrType.toString());
        	
        }
    }

    Output:

    AddressType=>Address:Address [addrLine1=121 Howard Lane, city=Orlando, state=FL, zip5=0]
    Address=>AddressType:AddressType [addrLine1=121 Howard Lane, city=Orlando, state=Florida, zipCode=0]

    References

    If you want to see dozer simple custom converter, please visit Dozer simple Custom converter example.

    Dozer custom converter with parameter

    Leave a Reply

    Your email address will not be published. Required fields are marked *