在使用orika做bean的转换的时候 ,我们会遇到不同字段不同类型的转换的情况。
一般的情况下,会简单的使用 fieldMap去做两个属性的转换。例如 ,我们有Article ,ArticleDTO,ArticleBO 三个Bean ,并且他们直接是继承关系,ArtilceBO extends ArticleDTO extends Article。
这个时候如果我们配置了 classMap(Article.class, ArticleDTO.class) classMap(ArticleDTO.class, ArticleBO.class) 这两个classMap 。需要把Article的 tagIdsJson 这个string 类型的转换成 ArticleDTO 的 List<Long> tagIds。按照之前的做法,首先注册一个转换器
converterFactory.registerConverter("articleTagIdsJsonToTagIds", new CustomConverter<String, List<Long>>() { @Override public List<Long> convert(String source, Type<? extends List<Long>> destinationType, MappingContext mappingContext) { if (Strings.isNullOrEmpty(source)) { return null; } else { return JSON.parseArray(source,Long.class); } } });
然后直接配置给两个属性
.fieldMap(TAG_IDS_JSON, TAG_IDS).converter("articleTagIdsJsonToTagIds").add()
这样的话会导致 在进行 ArticleDTO 转换到 ArticleBO 的时候会报错
java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.lang.String
由报错信息可知 在转换的时候 触发了 ArticleBO -> ArticleDTO ,ArticleDTO->Article两个Mapper 。但是,我们并没有配置tagIds -> tagIdsJson的转换,而换行默认是双向的。
解决方法:
1.指定单向转换
fieldMap(TAG_IDS_JSON, TAG_IDS).aToB().converter("articleTagIdsJsonToTagIds").add()
2.配置双向的转换器
converterFactory.registerConverter("articleTagIdsConverter", new BidirectionalConverter<String, List<Long>>() { @Override public List<Long> convertTo(String source, Type<List<Long>> destinationType, MappingContext mappingContext) { if (Strings.isNullOrEmpty(source)) { return null; } else { return JSON.parseArray(source,Long.class); } } @Override public String convertFrom(List<Long> source, Type<String> destinationType, MappingContext mappingContext) { if (CollectionUtils.isEmpty(source)) { return null; } else { return JSON.toJSONString(source); } } }); .fieldMap(TAG_IDS_JSON, TAG_IDS).converter("articleTagIdsConverter").add()