不同对象属性拷贝工具类
工作中我们存在不同平台数据同步问题,面临其他平台传过来的A对象要转换成我们自己需要的B对象,但是对象的很多属性字段不一样BeanUtils.copyProperties()只能拷贝相同属性的字段,这时候就需要我们一个一个去getset很麻烦
1.自定义一个注解,写一个工具类完成转换
/**
* 辅助通过反射技术实现对象属性的转换
* author: hx
* date: 2020/4/28
*/
@Target({ElementType.FIELD})
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface TargetField {
/**
* 目标字段
*/
String value() default "";
/**
* 字符串长度
*/
int length() default 0;
/**
* 字符串长度,是否自动截取
*/
boolean isAutoCut() default false;
/**
* 日期格式
*/
String format() default "yyyyMMdd";
/**
* 涉及到转换字符串时保留小数位,-1为不转换
*/
int scale() default -1;
/**
* 是否必填
*/
boolean required() default false;
}
2.我们需要的ConverterUtil
/**
* 对象转换器
* author: hx
* date: 2020/4/28
*/
public class ConverterUtil {
/**
* 从A对象转B对象
* 针对于字段上存在TargetField自定义注解的对象进行转换。
*
* @param source A对象
* @param target B对象
*/
public static void getTargetObj(Object source, Object target) {
Field[] fields = source.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
try {
TargetField targetField = field.getAnnotation(TargetField.class);
if (Objects.isNull(targetField)) continue;
Object value = field.get(source);
if (Objects.nonNull(value)) {
Field sapField = target.getClass().getDeclaredField(targetField.value());
sapField.setAccessible(true);
if (field.getType().equals(Date.class) && sapField.getType().equals(String.class)) {
value = DateUtils.formatDate((Date) value, targetField.format());
} else if (field.getType().equals(Boolean.class) && sapField.getType().equals(String.class)) {
Boolean b = (Boolean) value;
value = b ? "X" : "";
} else if (field.getType().equals(BigDecimal.class) && sapField.getType().equals(String.class) && targetField.scale() > -1) {
BigDecimal decimal = (BigDecimal) value;
value = decimal.setScale(targetField.scale(), BigDecimal.ROUND_HALF_UP).toString();
} else {
value = String.valueOf(value);
//截取字符串
if (targetField.isAutoCut() && ((String) value).length() > targetField.length()) {
value = ((String) value).substring(0, targetField.length());
}
}
sapField.set(target, value);
} else if (targetField.required()) {
throw new RuntimeException(String.format("字段%s(%s)不能为空!", field.getName(), targetField.value()));
}
} catch (Exception e) {
throw new RuntimeException("【getConverter】,错误信息:" + e.getMessage());
}
}
}
}
3.简单测试下
定义两个student对象
/**
* @author huxian
* @className Student01
* @description TODO
* @date 2020/4/28
*/
public class Student01 {
private String name;
private String password;
//省略getset toString
}
/**
* @author huxian
* @className Student02
* @description TODO
* @date 2020/4/28
*/
public class Student02 {
@TargetField(value = "name")
private String username;
private String password;
//省略getset toString
}
主方法测试
/**
* @author huxian
* @className TestConverter
* @description TODO
* @date 2020/4/28
*/
public class TestConverter {
public static void main(String[] args) {
//从student02拷贝属性到student01
Student02 student02 = new Student02();
student02.setUsername("笑话");
student02.setPassword("123456");
Student01 student01 = new Student01();
BeanUtils.copyProperties(student02,student01);
System.out.println("通过 BeanUtils.copyProperties拷贝的结果 :"+student01);
System.out.println("----------------------------------------------------");
ConverterUtil.getTargetObj(student02,student01);
System.out.println("通过 ConverterUtil.getTargetObj拷贝的结果 :"+student01);
}
}
测试结果