记录一些微服务开发中遇到的问题及解决思路、办法。
一、引言:
在web开发中,实体类的使用是参考阿里开发文档来定的,
image.png
request接收:用AO
response返回:用DTO
与数据库表一一对应的用:PO(本来想用DO但创建不了do的包名,所以改用PO)
业务对象:用BO
二、问题:
我们自己决定BO一定包含DTO所有的属性。
所以,经常要遇到BO转成DTO返回给前端,常规做法就是
- 构造函数new DTO(x,y,z,...);
- new DTO();然后set。。set。。。
很麻烦。。。。能不能直接转换?
三、思路:
发现springframework的BeanUtils自带拷贝属性方法:
image.png
然后,针对以上进行封装,然后使用。
四、解决:
我现在将RoleBO.java
转成RoleDTO
,只需要:RoleDTO roleDTO = MyBeanUtils.copyProperties(roleBO,RoleDTO.class);
即可。
五、源码:
源实体BO:
import lombok.Data;
import lombok.ToString;
@ToString(callSuper = true)
@Data
public class RoleBO {
private Long roleId;
private Integer roleLevel;
private String displayName;
private String note;
private Long uid;
}
目标实体DTO:
import lombok.Data;
import lombok.ToString;
@ToString(callSuper = true)
@Data
public class RoleDTO {
private Long uid;
private String displayName;
private String note;
}
测试:
public static void main(String[] args) {
RoleBO roleBO = new RoleBO();
roleBO.setUid(11111111L);
RoleDTO roleDTO = MyBeanUtils.copyProperties(roleBO,RoleDTO.class);
System.out.println(roleDTO.toString());
}
结果:
image.png
MyBeanUtils工具类:
package com.hongyi.cms.common;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.stereotype.Component;
import java.beans.PropertyDescriptor;
import java.util.HashSet;
import java.util.Set;
/**
*
* @param <S> 源对象
* @param <T> 目标对象类
*/
@Component
public class MyBeanUtils<S, T> {
/**
* 源对象属性绝对覆盖到目标对象。
* @param source
* @param targetClass
* @param <T>
* @return
* @throws Exception
*/
public static <T> T copyProperties(Object source, Class<T> targetClass) {
// 判断source是否为空
if (source == null)
return null;
// 判断targetClass是否为空
if (targetClass == null)
return null;
try {
T target = targetClass.newInstance();
BeanUtils.copyProperties(source, target);
return target;//向下转型
} catch (Exception e) {
System.out.println("pojo copyProperties failed! source:"+source.toString());
System.out.println("--------------------------------------------------------------");
System.out.println("targetClass:"+targetClass.getName());
return null;
}
}
/**
* 源对象上属性为null的,该属性不对目标进行覆盖。
* @param source
* @param targetClass
* @param <T>
* @return
* @throws Exception
*/
public static <T> T copyNotNullProperties(Object source, Class<T> targetClass) {
// 判断source是否为空
if (source == null)
return null;
// 判断targetClass是否为空
if (targetClass == null)
return null;
try {
T target = targetClass.newInstance();
String[] ignoreProperties = getNullPropertyNames(source);
BeanUtils.copyProperties(source, target, ignoreProperties);
return target;//向下转型
} catch (Exception e) {
System.out.println("pojo copyNotNullProperties failed! source:"+source.toString());
System.out.println("--------------------------------------------------------------");
System.out.println("targetClass:"+targetClass.getName());
return null;
}
}
public static String[] getNullPropertyNames(Object source) {
final BeanWrapper src = new BeanWrapperImpl(source);
PropertyDescriptor[] pds = src.getPropertyDescriptors();
Set<String> emptyNamesSet = new HashSet<>();
for (PropertyDescriptor pd : pds) {
Object sourceValue = src.getPropertyValue(pd.getName());
if (sourceValue == null) {
emptyNamesSet.add(pd.getName());
}
}
String[] result = new String[emptyNamesSet.size()];
return emptyNamesSet.toArray(result);
}
public static void copyNotNullProperties(Object source, Object target) {
String[] ignoreProperties = getNullPropertyNames(source);
BeanUtils.copyProperties(source, target, ignoreProperties);
}
public static void copyProperties(Object source, Object target) {
BeanUtils.copyProperties(source, target);
}
}
网友评论