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);
}
}
精彩评论