fastjson对象的序列化与反序列化踩得坑
作者:互联网
现象
最近使用RabbitMq发送消息时,遇到了提供者发送的消息(使用fastjson序列化数据对象)在消费者端转成(使用fastjson反序列化)数据对象后,属性缺失了
发送的消息对象:
/**
* 课本
**/
@Data
public class Book implements Serializable {
private static final long serialVersionUID = -4861445364356803601L;
private Integer id;
private String name;
private Integer type;
private String remark;
public Book(Integer id, String name) {
this.id = id;
this.name = name;
}
}
产生的现象如下图所示:
序列化对象后:
反序列化后:
上述现象可以看出,反序列化对象后,type 和 remark 属性值缺失了
原因
这里之所以出现这个问题,根本原因就是使用fastjson序列化与反序列化对象造成的,下面通过示例结合源码来分析一下成因:
1、无默认构造方法时,只有部分参数构造方法时(即只有 id,name 两个参数构成的构造方法)
对象:
运行断点调试:
运行结果:
得出结论:无默认构造方法时,构造bean属性从构造方法的参数中获取的(即只有id、name),因此反序列化时生成的对象会缺失 type 和 remark 的值
2、无默认构造方法时,有不同参数个数的多个构造方法
对象:
运行调试步骤如下图:
运行结果:
得出结论:无默认构造方法时,构造bean的属性使用最多参数(即有id、name、type、remark全部参数)的构造方法的所有参数,因此这里反序列化之后对象属性值没有缺失
3、有默认构造方法时,同时也有其他构造方法
对象:
运行调试步骤如下图:
运行结果:
得出结论:有默认构造方法时,优先使用默认构造方法,构造bean属性也是从所有的set方法中解析的,因此这里反序列化之后对象属性值不会缺失
最终结论
最后结论总结下来就2句话:
1、有默认构造方法时,优先使用默认构造方法,构造bean属性从所有的set方法中解析
2、无默认构造方法时,使用最多参数的构造方法,构造bean属性从最多参数构造方法中获取
解决方案
1、新建对象时最好加上默认构造方法
2、如果不想写默认构造方法,则需要写拥有所有参数的构造方法
源码
阅读的源码类(JavaBeanInfo)及方法(build):com.alibaba.fastjson.util.JavaBeanInfo#build(java.lang.Class<?>, java.lang.reflect.Type, com.alibaba.fastjson.PropertyNamingStrategy, boolean, boolean, boolean)
标签:fastjson,name,构造方法,对象,踩得,默认,序列化,id 来源: https://blog.csdn.net/ywlmsm1224811/article/details/97269539