We have seen how to customize the conversion of data from source POJO to Target POJO using XML mapping. And there is another way dozer provides us to control the flow by providing Events at various steps in flow through Event Listener interface i.e DozerEventListener.

DozerEventListener provides 4 operaions as under.Which are triggered in following sequence.

  1. mappingStarted(DozerEvent event) – triggered before mapping started. Executed once per mapping.
  2. preWritingDestinationValue(DozerEvent event) – triggered before field conversion. Executed for each field.
  3. postWritingDestinationValue(DozerEvent event) – triggered after field conversion. Executed for each field.
  4. mappingFinished(DozerEvent event) – triggered after mapping complete.

Using DozerEventListener, we could access dozer configuration and have option to modify at run time.In the below example, we can see how to skip specific fields at runtime.

Steps:

  • Create Source and Destination POJO classes
  • Create mapping xml
  • Implement DozerEventListener to skip specific fields
  • Attach DozerEventListener implementation and Run application
  • 1. Create Source and Destination POJO classes

    We created Source and destination POJO classes with one field in each.

    // PersType.java - Source POJO class
    public class PersType {
    	private String firstName;
    // Setters and Getters are removed	
    }
    //Person.java - Destination POJO class
    public class Person {
    
    	private String fName;
    // Setters and Getters are removed.	
    }
    

    2. Create mapping file.

    Lets create dozer mapping to map firstName in PersType to fName in Person domain.

    <?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>
    		<class-a>com.codesimplify.dozersamples.events.PersType</class-a>
    		<class-b>com.codesimplify.dozersamples.events.Person</class-b>
    		<field>
    			<a>firstName</a>
    			<b>fName</b>
    		</field>		
    	</mapping>
    </mappings>

    3. Implement DozerEventListener.

    To explain how it works, i implemented mappingStarted() to explain how to skip firstName field dynamically during mapping.

    public class CustomEventListener implements DozerEventListener {
    
    	public void mappingStarted(DozerEvent event) {
    		System.out.println("In side mappingStarted");
    		
    		List removeList=new ArrayList();
    		for (FieldMap fieldMap : event.getClassMap().getFieldMaps()) {
    			if("firstName".equals(fieldMap.getSrcFieldName()) ){
    				removeList.add(fieldMap);
    				
    			}
    		}
    		if(!removeList.isEmpty()){
    			event.getClassMap().getFieldMaps().removeAll(removeList);
    		}		
    		System.out.println(event.getDestinationObject());
    		System.out.println(event.getDestinationValue());
    		System.out.println(event.getType());
    		System.out.println(event.getSourceObject());
    
    	}
    
    	public void preWritingDestinationValue(DozerEvent event) {
    		System.out.println("In side preWritingDestinationValue");
    		System.out.println(event.getDestinationObject());
    		System.out.println(event.getDestinationValue());
    		System.out.println(event.getType());
    		System.out.println(event.getSourceObject());
    
    	}
    
    	public void postWritingDestinationValue(DozerEvent event) {
    		System.out.println("In side postWritingDestinationValue");
    		System.out.println(event.getDestinationObject());
    		System.out.println(event.getDestinationValue());
    		System.out.println(event.getType());
    		System.out.println(event.getSourceObject());
    
    	}
    
    	public void mappingFinished(DozerEvent event) {
    		System.out.println("In side mappingFinished");
    		System.out.println(event.getDestinationObject());
    		System.out.println(event.getDestinationValue());
    		System.out.println(event.getType());
    		System.out.println(event.getSourceObject());
    
    	}
    
    }
    

    4. Attach DozerEventListener implementation to DozerBeanMapper and Run Application.

    If you notice the output, before implementing CustomEventListener.mappingStarted() to skip firstName field, we can see all events are executed. Once we skipped firstName, field specific events( preWritingDestinationValue(), postWritingDestinationValue() ) are not triggered. And firstName is not copied to fName as well.

    public class App_DozerEventListener_Example 
    {
        public static void main( String[] args )
        {
        	DozerBeanMapper mapper=new DozerBeanMapper();
        	// Load Mapping files
        	List myMappingFiles = new ArrayList();
        	myMappingFiles.add("DozerMappings_events.xml");
        	mapper.setMappingFiles(myMappingFiles);
        	// Attach Event Listeners
        	List list=new ArrayList();
        	list.add(new CustomEventListener());
        	mapper.setEventListeners(list);
        	
        	PersType persType=new PersType();
        	persType.setFirstName("venkat");
        	
    		
        	Person person=mapper.map(persType, Person.class);
        	// Convert PersType to Person Domain
        	System.out.println("PersType=>Person:"+person.toString());
     	
        }
    }

    Output:

    Event Sequence Before Skipping field Event Sequence After Skipping field
    In side mappingStarted
    null
    null
    MAPPING_STARTED
    PersType [firstName=venkat]
    In side preWritingDestinationValue
    Person [fName=null]
    venkat
    MAPPING_PRE_WRITING_DEST_VALUE
    PersType [firstName=venkat]
    In side postWritingDestinationValue
    Person [fName=venkat]
    venkat
    MAPPING_POST_WRITING_DEST_VALUE
    PersType [firstName=venkat]
    In side mappingFinished
    Person [fName=venkat]
    null
    MAPPING_FINISHED
    PersType [firstName=venkat]
    PersType=>Person:Person [fName=venkat]
    In side mappingStarted
    null
    null
    MAPPING_STARTED
    PersType [firstName=venkat]
    In side mappingFinished
    Person [fName=null]
    null
    MAPPING_FINISHED
    PersType [firstName=venkat]
    PersType=>Person:Person [fName=null]

    References

    Dozer Event Listener Guide

    Dozer Event Listener( DozerEventListener ) example

    Leave a Reply

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