DozerMapper将String转LocalDateTime问题(Unsupported source object type: class java.lang.String)

前言

  1. 在项目中由于需要将bean转DTO转VO,或者Map到bean等场景都涉及到类对象属性拷贝,如果字段少的话,手动set也是ok的,要是多的话就嘿嘿嘿了,还是懒点好
  2. 对比了比较热门的工具如:BeanCopier、BeanUtils、DozerBeanMapper、PropertyUtils,
    不得不说BeanCopier性能是真的强,由于本人项目中VO存在多层嵌套的情况,所以考虑使用DozerBeanMapper来实现,因为它支持深拷贝,

问题

在String转LocalDateTime类型时,报错:Unsupported source object type: class java.lang.String,排查了一下问题所在:
报错的逻辑是:

if (TemporalAccessor.class.isAssignableFrom(srcObjectClass)) {
	Method method = destClass.getDeclaredMethod("from", TemporalAccessor.class);
    return method.invoke(null, (TemporalAccessor)srcObject);
} else if (String.class.isAssignableFrom(srcObjectClass) && formatter != null) {
    Method method = destClass.getDeclaredMethod("parse", CharSequence.class, DateTimeFormatter.class);
    return method.invoke(null, srcObject, formatter);
} else {
    throw new ConversionException(String.format("Unsupported source object type: %s", srcObjectClass), null);
}

代码拷贝自AbstractJava8DateTimeConverter#convert
显然formatter为null导致,

解决方案:

一:配置formatter

<field>
  <a date-format="MM/dd/yyyy HH:mm:ss:SS">dateStringa>
  <b>dateObjectb>
field>

具体请查看官网[http://dozer.sourceforge.net/documentation/stringtodatemapping.html]

二:通过CustomFieldMapper来实现

代码如下:

private static final Mapper MAPPER = DozerBeanMapperBuilder.create().withCustomFieldMapper((source, destination, sourceFieldValue, classMap, fieldMapping) -> {
        Class<?> destFieldType = fieldMapping.getDestFieldType(BuilderUtil.unwrapDestClassFromBuilder(destination));
        if (LocalDateTime.class.getTypeName().equals(destFieldType.getTypeName()) && String.class.getTypeName().equals(sourceFieldValue.getClass().getTypeName())) {
            fieldMapping.writeDestValue(destination, LocalDateTime.parse((CharSequence) sourceFieldValue, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            return true;
        }
        return false;
    }).build();

当然,也可以通过Spring的容器来管理这个Singleton

你可能感兴趣的:(java,笔记)