Orika 1.5.2 HashMap转Bean时String转Date报错,转换器无效如何解决?
解决Orika从Map到Bean时String转Date的类型转换异常问题
问题根源
你遇到的ClassCastException其实有两个关键原因:
- 你注册的
DateToStringConverter是Date转String的转换器,和你需要的String转Date方向完全相反,根本匹配不上当前场景; - Orika处理
Map到JavaBean的映射时,因为Map的value是泛型擦除后的Object类型,默认不会自动触发类型转换器,而是直接尝试强制类型转换,这就导致String无法直接转成Date抛出异常。
而Bean之间映射正常,是因为两个Bean的字段有明确的类型声明,Orika能识别到源类型和目标类型的差异,自动匹配对应的转换器。
解决方案
下面提供两种可行的解决方法,你可以根据需求选择:
方法一:注册正确的转换器+配置Map类型解析策略
先注册String转Date的转换器,再让Orika在处理Map时能识别目标Bean的字段类型,从而触发转换器:
import ma.glasnost.orika.MapperFactory; import ma.glasnost.orika.converter.builtin.ToStringDateConverter; import ma.glasnost.orika.impl.DefaultMapperFactory; import java.util.Date; import java.util.HashMap; public class UserA { private Date birthday; public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } @Override public String toString() { return "UserA [birthday=" + birthday + "]"; } } public class Main { public static void main(String[] args){ HashMap<String, Object> map = new HashMap<>(); map.put("birthday", "2014-04-28"); UserA ua = new UserA(); MapperFactory mapF = new DefaultMapperFactory.Builder() .mapNulls(false) // 关键配置:让Orika把Map当作ClassMap处理,识别目标Bean的字段类型 .mapAsClassMap() .build(); // 注册String转Date的转换器,指定你的日期格式 mapF.getConverterFactory().registerConverter(new ToStringDateConverter("yyyy-MM-dd")); mapF.getMapperFacade().map(map, ua); System.out.println(ua); // 输出:UserA [birthday=Mon Apr 28 00:00:00 CST 2014] } }
方法二:针对特定字段配置转换器
如果你只需要处理个别字段的转换,可以给特定字段单独注册转换器,更精准:
import ma.glasnost.orika.MapperFactory; import ma.glasnost.orika.converter.builtin.ToStringDateConverter; import ma.glasnost.orika.impl.DefaultMapperFactory; import java.util.Date; import java.util.HashMap; public class UserA { private Date birthday; public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } @Override public String toString() { return "UserA [birthday=" + birthday + "]"; } } public class Main { public static void main(String[] args){ HashMap<String, Object> map = new HashMap<>(); map.put("birthday", "2014-04-28"); UserA ua = new UserA(); MapperFactory mapF = new DefaultMapperFactory.Builder() .mapNulls(false) .build(); // 给UserA的birthday字段绑定String转Date的转换器 mapF.classMap(HashMap.class, UserA.class) .field("birthday", "birthday") .converter(new ToStringDateConverter("yyyy-MM-dd")) .register(); mapF.getMapperFacade().map(map, ua); System.out.println(ua); } }
额外补充:自定义转换器(如果自带转换器不满足需求)
如果自带的ToStringDateConverter无法适配你的特殊日期格式,你可以自己写一个转换器:
import ma.glasnost.orika.Converter; import ma.glasnost.orika.MappingContext; import ma.glasnost.orika.metadata.Type; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class StringToDateConverter implements Converter<String, Date> { private final SimpleDateFormat dateFormat; public StringToDateConverter(String pattern) { this.dateFormat = new SimpleDateFormat(pattern); } @Override public Date convert(String source, Type<? extends Date> destinationType, MappingContext mappingContext) { try { return dateFormat.parse(source); } catch (ParseException e) { throw new RuntimeException("日期转换失败", e); } } @Override public boolean canConvert(Type<?> sourceType, Type<?> destinationType) { return String.class.equals(sourceType.getRawType()) && Date.class.equals(destinationType.getRawType()); } }
注册和使用方式和自带的转换器完全一致,替换掉ToStringDateConverter即可。
内容的提问来源于stack exchange,提问作者chenw
相关产品推荐
相关产品推荐

