简体   繁体   中英

Mapping primitive classes (String, Boolean, etc) to each other with Dozer

I'm trying to use Dozer to automatically map from primitive classes to each other. At the end, the code might end up looking like this.

Boolean resultBoolean = mapper.map("true", Boolean.class);

While Dozer does support mapping String to Boolean when in a bean, it seems mapping directly to Boolean produces the following exception.

org.dozer.MappingException: java.lang.NoSuchMethodException: java.lang.Boolean.<init>()
at org.dozer.util.MappingUtils.throwMappingException(MappingUtils.java:88)
at org.dozer.factory.ConstructionStrategies$ByConstructor.newInstance(ConstructionStrategies.java:261)
at org.dozer.factory.ConstructionStrategies$ByConstructor.create(ConstructionStrategies.java:245)
at org.dozer.factory.DestBeanCreator.create(DestBeanCreator.java:65)
at org.dozer.MappingProcessor.map(MappingProcessor.java:178)
at org.dozer.MappingProcessor.map(MappingProcessor.java:125)
at org.dozer.MappingProcessor.map(MappingProcessor.java:120)
at org.dozer.DozerBeanMapper.map(DozerBeanMapper.java:111)

...

Caused by: java.lang.NoSuchMethodException: java.lang.Boolean.<init>()
at java.lang.Class.getConstructor0(Class.java:2706)
at java.lang.Class.getDeclaredConstructor(Class.java:1985)
at org.dozer.factory.ConstructionStrategies$ByConstructor.newInstance(ConstructionStrategies.java:257)
... 32 more

It is clear that Dozer is trying to instantiate the Boolean itself. I'm able to create a customer DozerConverter to convert Boolean to String, but I don't want to re-implement the code that Dozer already has. Is there any way to get Dozer to map to and from primitive types directly?

You could use org.dozer.converters.PrimitiveOrWrapperConverter instead of org.dozer.DozerBeanMapper :

import org.dozer.converters.DateFormatContainer;
import org.dozer.converters.PrimitiveOrWrapperConverter;

public class DozerPrimitiveMapping {


    public static void main(String[] args) {

        PrimitiveOrWrapperConverter primitiveConverter = new PrimitiveOrWrapperConverter();
        //DateFormatContainer is not needed in this String-to-Boolean use case, but the converter would throw an error if it was null
        DateFormatContainer dateFormatContainer = new DateFormatContainer("");
        Boolean booleanResult= (Boolean) primitiveConverter.convert("true", Boolean.class, dateFormatContainer);
        System.out.println("Boolean result from dozer: "+booleanResult);
    }
}

Or wrap it all up in a custom converter:

package my.dozer.test;

import org.dozer.CustomConverter;
import org.dozer.converters.DateFormatContainer;
import org.dozer.converters.PrimitiveOrWrapperConverter;

public class DozerPrimitiveConverter implements CustomConverter {

    private final PrimitiveOrWrapperConverter primitiveConverter = new PrimitiveOrWrapperConverter();
    //DateFormatContainer is not needed in this String-to-Boolean use case, but the converter would throw an error if it was null
    private final DateFormatContainer dateFormatContainer = new DateFormatContainer("");

    @Override
    public Object convert(Object existingDestinationFieldValue, Object sourceFieldValue, Class<?> destinationClass, Class<?> sourceClass) {
        Boolean booleanResult = (Boolean) primitiveConverter.convert(sourceFieldValue, Boolean.class, dateFormatContainer);
        return booleanResult;
    }

}

And configure the converter like it is in this example configuration file dozer-primitive-mapping.xml :

<?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">

    <configuration>
        <custom-converters>
          <converter type="my.dozer.test.DozerPrimitiveConverter" >
              <class-a>java.lang.String</class-a>
              <class-b>java.lang.Boolean</class-b>
          </converter>
        </custom-converters>
    </configuration>

</mappings>

Example class to run the mapping with using the custom converter:

package my.dozer.test;

import java.io.InputStream;
import org.dozer.DozerBeanMapper;

public class DozerPrimitiveConverterApp {

    public static void main(String[] args) {
        DozerBeanMapper mapper = new DozerBeanMapper();
        InputStream is = DozerPrimitiveConverterApp.class.getClassLoader().getResourceAsStream("dozer-primitive-mapping.xml");
        mapper.addMapping(is);

        Boolean booleanValue = mapper.map("false", Boolean.class);
        System.out.println("Boolean result from dozer with custom converter: " + booleanValue);

    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM