通过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;

}

业务场景

  1. 这是一个SpringBoot工程,A是通过feign调用其他服务获取到的,B是本工程的一个Controller接口的返回值
  2. A和B里面的字段其实是一模一样的,B的字段和值来源均为A
    1. 没有直接使用A的原因是:Controller接口的出入参和feign接口的出入参不共用一套,两者解耦开,避免feign接口出入参有修改,controller接口未做调整,前端或其他调controller接口的服务使用出错
    2. 故而B里面的字段可以命名为id(和A保持一致),或者命名为bId(和A 不一致,但值就是A中id的值)
  3. 由于A里面有个List类型的A,即便把B里面的字段完全命名成和A中的字段一样,直接BeanUtils.copyProperties(a, b)也未能成功:B里面的List类型的B值为空
  4. 经分析:可以将A序列化为json,再将json串反序列化为B。
    1. 但是id怎么转换成bId呢,jackson已经提供了此类功能,通过@JsonProperty注解给属性起另一个想要的名称进行转换。
    2. 另外也支持时间类型的字段的转换:通过@JsonFormat注解配置日期格式,可以格式化日期属性。
  5. 进而调整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));
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值