背景:在对外传输数据展示过程中,为了避免model层直接对外暴露,我们会多加一个对应的DTO保理想要传输的数据即可,隐藏model层。
应对:
1.第一种,如果是实体类字段类型都一样,大部分会采用bean拷贝的方式,BeanUtils.copyProperties(obj,obj),单个对象的转换还好,但是List对象就要循环来转换。
2.第二种,要是遇到驼峰类型字段与下划线字段的对象进行转换也是头疼,由于可能接口跟实体类不是一波人写的,在一致性上没用做统一的规范,导致model和DTO的字段类型还不一样。这种fastJson有对应的转换
/**
* 将对象的大写转换为下划线加小写,例如:userName-->user_name
*
* tar 目标对象
* to 转换对象
* @return
* @throws Exception
*/
public static Object toUnderline(Object tar,Object to) throws Exception {
SerializeConfig config = new SerializeConfig();
config.propertyNamingStrategy = PropertyNamingStrategy.SnakeCase;
String json=JSON.toJSONString(tar,config);
return JSON.parseObject(json, to.getClass());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
SnakeCase 就是一种转换下划线的策略,当然也是可以互转的,只要修改策略的枚举值为CamelCase,就转为驼峰。
3.第三种,为了保持我们提供的接口代码尽量的简洁,当然不希望语句块中存在无关逻辑的转换实体类的语句,相对来说modelmapper提供了一个比较好的方式
pom依赖
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>${modelmapper.version}</version>
</dependency>
1
2
3
4
5
ModelMapper modelMapper = new ModelMapper();
//单个转换
ProductInfo productInfo = service.getOne();
ProductInfoDto dto = modelMapper.map(productInfo,ProductInfoDto.calss);
//list转换
List<ProductInfo> productInfos =service.getList();
List<ProductInfoDto> productInfoDtos = modelMapper.map(productInfos, new TypeToken<List<ProductInfoDto>>() {
}.getType());