背景:
小伙伴们大家好,最近开发的时候遇到一种情况,项目引入了全局序列化器来实现Date,LocalDateTime类型的字段根据时区转换,总体来说接口没什么要改动的,只要原来字段的属性是以上两种就行,但是存在一些String类型的日期字段,该种类型日期字段需要手动改为Date或者LocalDateTime类型
思路:
因为只用改动String类型的字段,实体类的其他属性直接复制原来的就行,所以直接借助springboot框架中对象拷贝的工具类,然后自定义String类型的日期转换即可
自定义赋值过程源码、如下
//是一个泛型方法
public static <T> T copyAndConvertDate(Object source, Class<T> target, String... dataTimeFields) {
//source:源对象,就是要从中复制属性值的对象
//target:目标类,要创建并接收复制属性的目标类
//dateTimeFields: 哪些日期字段要处理
T copiedObject = BeanUtils.instantiateClass(target);
//创建目标类的实例
BeanUtils.copyProperties(source, copiedObject);
//源对象属性值 》》 目标对象
BeanWrapperImpl beanWrapper = new BeanWrapperImpl(copiedObject);
//用来操作目标对象的属性
for (String field : dataTimeFields) {
try {
Field declaredField = source.getClass().getDeclaredField(field);
declaredField.setAccessible(true);
String fieldValue = (String) declaredField.get(source);
//反射获取源对象中对应的指定字段,并设置为可以访问(因为是私有属性)
if (fieldValue != null && fieldValue.matches("\\d{2}-[a-zA-Z]{3}-\\d{4}")) {
//这种格式的“23-Jan-2024"的值,走该处理代码
Date dateTime = new SimpleDateFormat("dd-MMM-yyyy", Locale.US).parse(fieldValue);
//解析为Date对象
beanWrapper.setPropertyValue(field, dateTime);
//更改目标对象指定字段的属性值
} else {
Date dateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm").parse(fieldValue);
beanWrapper.setPropertyValue(field, dateTime);
}
} catch (Exception e) {
e.printStackTrace();
log.error("拷贝对象属性:{} -> {} 出错", field, target);
}
}
return copiedObject;
//返回目标对象
}
apipost测试下
原先的实体类
@Data
public class BlockStructureVO {
private String issueTime;
...//其他属性
}
目标实体类
@Data
public class NewBlockStructureVO {
private Date issueTime;
...//其他属性不变
}
转换代码块
NewBlockStructureVO newBlockStructureVO = BeanUtil.copyAndConvertDate(blockStructureVO, NewBlockStructureVO.class, "issueTime");
//source: blockStructureVO
//target: NewBlockStructureVO.class
//指定字段:issueTime
调试一下看看旧的对象和新的对象区别
旧的
新的
对比发现确实只有指定的字段值改变了,别的属性与旧的对象属性相同