日常开发中肯定免不了要对Bean对象进行映射或是类型转换,比如常用的Spring的BeanUtils,cglib的BeanCopier这种对象属性复制的工具,可以省去大量的get/set的代码。
由于上述属性复制工具是按照字段名、字段类型通过反射进行复制的,所以如果碰到两个对象中同一个字段的字段类型不一致,是不能成功赋值的。对于这种情况,可以使用orika解决。
Orika进行对象转换时,可以对指定类型进行自定义转换逻辑。例如将String与Map互相转换,将Byte与Integer互相转换,甚至也可以对指定的两个自定义Bean进行转换逻辑自定义。因为Orika进行对象转换时,是根据要转换的两个字段类型取查找是否有自定义的类型转换器,使用代码示例如下:
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import ma.glasnost.orika.CustomConverter;
import ma.glasnost.orika.MapperFacade;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.MappingContext;
import ma.glasnost.orika.converter.BidirectionalConverter;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import ma.glasnost.orika.metadata.Type;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* Orika对象转换配置
*
* @author Danger
*/
@Configuration
public class OrikaConfig {
private MapperFactory mapperFactory() {
DefaultMapperFactory factory = new DefaultMapperFactory.Builder().build();
//自定义字段映射
// Map与String
factory.getConverterFactory().registerConverter(new BidirectionalConverter<Map<String, Object>, String>() {
@Override
public String convertTo(Map<String, Object> source, Type<String> destinationType, MappingContext mappingContext) {
if (source != null) {
return JSON.toJSONString(source, SerializerFeature.WriteDateUseDateFormat);
}
return "";
}
@Override
public Map<String, Object> convertFrom(String source, Type<Map<String, Object>> destinationType, MappingContext mappingContext) {
if (StringUtils.isNotEmpty(source)) {
return JSON.parseObject(source);
}
return new JSONObject();
}
});
// Byte与Boolean
factory.getConverterFactory().registerConverter(new BidirectionalConverter<Byte, Boolean>() {
@Override
public Boolean convertTo(Byte source, Type<Boolean> destinationType, MappingContext mappingContext) {
return source != null && source > 0;
}
@Override
public Byte convertFrom(Boolean source, Type<Byte> destinationType, MappingContext mappingContext) {
return (source != null && source) ? new Byte("1") : new Byte("0");
}
});
// Byte与Integer
factory.getConverterFactory().registerConverter(new BidirectionalConverter<Byte, Integer>() {
@Override
public Integer convertTo(Byte source, Type<Integer> destinationType, MappingContext mappingContext) {
return source == null ? 0 : (int)source;
}
@Override
public Byte convertFrom(Integer source, Type<Byte> destinationType, MappingContext mappingContext) {
return source == null ? 0 : new Byte(source.toString());
}
});
return factory;
}
@Bean
public MapperFacade mapperFacade() {
return mapperFactory().getMapperFacade();
}
/**
* 测试demo
*
*/
public static void main(String[] args) {
OrikaConfig orikaConfig = new OrikaConfig();
MapperFacade mapperFacade = orikaConfig.mapperFacade();
Map<String, Object> map = new HashMap<>();
map.put("mapKey", new Date());
A a = new A();
B b = new B();
a.setMap(map);
a.setNum(1);
a.setBb((byte)1);
mapperFacade.map(a, b);
System.out.println(JSON.toJSONString(a));
System.out.println(JSON.toJSONString(b));
b.setMap("{\"strKey\":\"strValue\"}");
b.setNum(new Byte("2"));
b.setBb(false);
mapperFacade.map(b, a);
System.out.println(JSON.toJSONString(b));
System.out.println(JSON.toJSONString(a));
}
}
class A {
private Map<String, Object> map;
private Integer num;
private Byte bb;
public Map<String, Object> getMap() {
return map;
}
public void setMap(Map<String, Object> map) {
this.map = map;
}
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
public Byte getBb() {
return bb;
}
public void setBb(Byte bb) {
this.bb = bb;
}
}
class B {
private String map;
private Byte num;
private Boolean bb;
public String getMap() {
return map;
}
public void setMap(String map) {
this.map = map;
}
public Byte getNum() {
return num;
}
public void setNum(Byte num) {
this.num = num;
}
public Boolean getBb() {
return bb;
}
public void setBb(Boolean bb) {
this.bb = bb;
}
}