通过Jackson序列化反序列化解决对象拷贝问题
Posted mada26
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通过Jackson序列化反序列化解决对象拷贝问题相关的知识,希望对你有一定的参考价值。
问题背景
最近在项目中遇到一个对象拷贝的问题,无法直接使用BeanUtils.copyProperties(a, b);且使用get set比较麻烦。拷贝涉及到的两个类信息如下:
// 省略get set方法
public class A
private int id;
private String name;
private List<A> list;
private Date birthday;
private LocalDateTime localDateTime;
// 省略get set方法
public class B
private int bId;
private String bName;
private List<B> bList;
private Date myBirthday;
private LocalDateTime localDateTime;
业务场景
- 这是一个SpringBoot工程,A是通过feign调用其他服务获取到的,B是本工程的一个Controller接口的返回值
- A和B里面的字段其实是一模一样的,B的字段和值来源均为A
- 没有直接使用A的原因是:Controller接口的出入参和feign接口的出入参不共用一套,两者解耦开,避免feign接口出入参有修改,controller接口未做调整,前端或其他调controller接口的服务使用出错
- 故而B里面的字段可以命名为id(和A保持一致),或者命名为bId(和A 不一致,但值就是A中id的值)
- 由于A里面有个List类型的A,即便把B里面的字段完全命名成和A中的字段一样,直接BeanUtils.copyProperties(a, b)也未能成功:B里面的List类型的B值为空
- 经分析:可以将A序列化为json,再将json串反序列化为B。
- 但是id怎么转换成bId呢,jackson已经提供了此类功能,通过
@JsonProperty注解
给属性起另一个想要的名称进行转换。 - 另外也支持时间类型的字段的转换:通过
@JsonFormat注解
配置日期格式,可以格式化日期属性。
- 但是id怎么转换成bId呢,jackson已经提供了此类功能,通过
- 进而调整B的代码如下:
// 省略get set方法
public class B
// @JsonProperty 在序列号和反序列化时使用,作用于属性上,作用是把该属性的名称序列化成另一个自己想要的名称。
@JsonProperty("id")
private int bId;
@JsonProperty("name")
private String bName;
@JsonProperty("list")
private List<B> bList;
// @JsonFormat 格式化日期属性
@JsonProperty("birthday")
@JsonFormat(pattern = "yyyy年MM月dd日")
private Date myBirthday;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime localDateTime;
这样就可以通过json序列化、反序列化实现了对象的拷贝。List<A>
转换成List<B>
同理,也可以这样转换。
@Test
public void t1()
A a = A.builder().id(1).name("name1").list(
Arrays.asList(
A.builder().id(10).name("name10").list(
Arrays.asList(
A.builder().id(100).name("name100").list(new ArrayList<>()).build(),
A.builder().id(101).name("name101").list(new ArrayList<>()).build()
))
.build(),
A.builder().id(11).name("name11").list(new ArrayList<>()).build())
)
.birthday(new Date())
.localDateTime(LocalDateTime.now())
.build();
String str = JacksonUtils.writeAsString(a);
B b = JacksonUtils.readValue(str, B.class);
System.out.println(JacksonUtils.writeAsString(b));
以上是关于通过Jackson序列化反序列化解决对象拷贝问题的主要内容,如果未能解决你的问题,请参考以下文章