Orika 实现 Map 和 Entity 之间转换(类型不匹配)

一、背景

Map 对象:

Map<String, Object> map = new HashMap<>();
map.put("name", "max");
map.put("age", 18);

User 实例:

@Data
public class User {
    private String name;
    private Byte age;
}

转换代码:

MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
MapperFacade mapper = mapperFactory.getMapperFacade();

mapper.map(map, User.class);

结果:

Error occurred: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Byte

二、原因

首先要说明的是,Orika 默认是支持 Map 对象和一般对象之间的转换的,这里报错的原因,其实是我们在 HashMap 中放入的 age 值是 Integer 类型,而 User 类中定义的 age 字段为 Byte 类型导致的。

三、解决

遇到该问题第一个想到的就是添加 OrikaCustom Converters 配置,于是做如下调整。

public class IntegerToByteConverter extends CustomConverter<Integer, Byte> {
    @Override
    public Byte convert(Integer source, Type<? extends Byte> destinationType, MappingContext context) {
        return source.byteValue();
    }
}
MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
mapperFactory.getConverterFactory().registerConverter(new IntegerToByteConverter());
MapperFacade mapper = mapperFactory.getMapperFacade();

mapper.map(map, User.class);

然而,依旧报相同的错误。

我的理解是,Orika 并不能识别出 HashMap 对象中 age 对应值的类型(Integer),而是直接根据 Map 定义的类型(Object)来判断和使用定义的 Converter 的,所以其实要定义的是 ObjectByte 之间的转换器,如下。

public static class ObjectToByteConverter extends CustomConverter<Object, Byte> {
    @Override
    public Byte convert(Object source, Type<? extends Byte> destinationType, MappingContext context) {
        if (source instanceof Integer) {
            return ((Integer) source).byteValue();
        }
        return null;
    }
}
MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
mapperFactory.getConverterFactory().registerConverter(new ObjectToByteConverter());
MapperFacade mapper = mapperFactory.getMapperFacade();

mapper.map(map, User.class);

现在可以成功转换了。

参考:

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容