How to use Dozer with Spring Boot?
Asked Answered
I

3

12

I am working on a Spring Boot project. I just have annotation configuration. I want to include dozer to transform Entities to DTO and DTO to Entities. I see in the dozer website, they explain i have to add the following configuration in spring xml configuration file. Since i have not xml file but annotation configuration Java class, i don't know how to translate this into Java Configuration class.

<bean id="org.dozer.Mapper" class="org.dozer.DozerBeanMapper">
  <property name="mappingFiles">
    <list>
      <value>dozer-global-configuration.xml</value>
      <value>dozer-bean-mappings.xml</value>
      <value>more-dozer-bean-mappings.xml</value>
    </list>
  </property>
</bean>

If someone could you give me an example it'll be very useful. Thanks

Indian answered 6/2, 2015 at 15:44 Comment(1)
Why not to use DozerBeanMapperSingletonWrapper.getInstance()?Countrybred
N
19

I think something like this should work:

@Configuration
public class YourConfiguration {

  @Bean(name = "org.dozer.Mapper")
  public DozerBeanMapper dozerBean() {
    List<String> mappingFiles = Arrays.asList(
      "dozer-global-configuration.xml", 
      "dozer-bean-mappings.xml",
      "more-dozer-bean-mappings.xml"
    );

    DozerBeanMapper dozerBean = new DozerBeanMapper();
    dozerBean.setMappingFiles(mappingFiles);
    return dozerBean;
  }

  ...
}
Nigercongo answered 6/2, 2015 at 20:33 Comment(1)
Thank your for your suggestions. It's what i am doing.Indian
W
10

If you are using DozerBeanMapperFactoryBean instead of DozerBeanMapper you may use something like this.

@Configuration
public class MappingConfiguration {

    @Bean
    public DozerBeanMapperFactoryBean dozerBeanMapperFactoryBean(@Value("classpath*:mappings/*mappings.xml") Resource[] resources) throws Exception {
        final DozerBeanMapperFactoryBean dozerBeanMapperFactoryBean = new DozerBeanMapperFactoryBean();
        // Other configurations
        dozerBeanMapperFactoryBean.setMappingFiles(resources);
        return dozerBeanMapperFactoryBean;
    }
}

This way you can import your mappings automatically. Than simple inject your Mapper and use.

@Autowired
private Mapper mapper;

Update with Dozer 5.5.1

In dozer 5.5.1, DozerBeanMapperFactoryBean is removed. So if you want to go with an updated version you need do something like below,

@Bean
public Mapper mapper(@Value(value = "classpath*:mappings/*mappings.xml") Resource[] resourceArray) throws IOException {
    List<String> mappingFileUrlList = new ArrayList<>();
    for (Resource resource : resourceArray) {
        mappingFileUrlList.add(String.valueOf(resource.getURL()));
    }
    DozerBeanMapper dozerBeanMapper = new DozerBeanMapper();
    dozerBeanMapper.setMappingFiles(mappingFileUrlList);
    return dozerBeanMapper;
}

Now inject mapper as told above

@Autowired
private Mapper mapper;

And use like below example,

mapper.map(source_object, destination.class);

eg. mapper.map(admin, UserDTO.class);

Wahoo answered 19/10, 2015 at 13:27 Comment(3)
Late to the party here, but I can't find org.dozer.spring package in the Dozer 5.5.1 release. Has DozerBeanMapperFactoryBean been replaced/moved?Parkland
@Parkland yes it removed in Dozer 5.5.1.Alienism
Can be improved slightly by using: new DozerBeanMapper(mappingFileUrlList)Beautician
E
9

Just in case someone wants to avoid xml dozer file. You can use a builder directly in java. For me it's the way to go in a annotation Spring context.

See more information at mapping api dozer

    @Bean
public DozerBeanMapper mapper() throws Exception {
    DozerBeanMapper mapper = new DozerBeanMapper();
    mapper.addMapping(objectMappingBuilder);
    return mapper;
}

BeanMappingBuilder objectMappingBuilder = new BeanMappingBuilder() {
    @Override
    protected void configure() {
        mapping(Bean1.class, Bean2.class)
                .fields("id", "id").fields("name", "name");
    }
};

In my case it was more efficient (At least the first time). Didn't do any benchmark or anything.

Entablature answered 15/2, 2017 at 4:42 Comment(4)
this is good but if u have 20 fields to map u will repeat this .fields("id", "id").fields("name", "name"); 20 times?Regatta
You could try to use annotation in your class dozer.sourceforge.net/documentation/annotations.htmlEntablature
what I understood is we don't have to put annotation in all fields private Long id; private String name; in target class all fields will be mapped even though we have only one field mapped ? @Mapping("binaryData") private String data;Regatta
I haven't tried but it's my understanding. You can exclude fields if it's what you need.Entablature

© 2022 - 2024 — McMap. All rights reserved.