问题描述
将Message对象
序列化后,反序列化失败。
response
是序列化的结果,start
为true
,end
为false
。
message
是反序列化后的对象,start
和end
都为false。
问题解决
1.资料查找
经过自己的初步debug后,并没有任何的头绪,所以google了一下网上的解决办法。
因为content
正确反序列化了,所以认为是boolean
的问题,就去查关于反序列化布尔值的文章。
然而大面积都是类似下面这种标题的文章:
好像跟我的问题有点不同,但是还是抱着借鉴的心态看了几篇。结果如预期,并没有什么用。但是从其中一片发现boolean
和Boolean
在反序列化时的处理有点不同。所以开始进行尝试。
2.初步尝试
这是一开始我实体中的字段设置,start
和end
都是基本类型。
然后将他们改成封装类型Boolean
,再来看一下结果:
start
和end
变成了null
,依然失败。
然后官方也提到了,boolean
默认为false
,而Boolean
默认为null
。也就是说,引起上面问题的原因是在反序列化的时候,start
和end
两个属性没有值。
3.再次尝试
又查了几篇相关的文章后,依然没有解决问题。所以想干脆使用String
算了,进行字符传递。
然而,依然失败。但是既然同样是String
类型的,content
能够成功反序列化,为什么start
和end
就不行呢?
然后就开始了找不同。发现了问题的所在。
这里我写了一个自己的构造函数,但是参数只有content
,而没有另外的参数。
4.问题解决
找到了不同之后,问题就好解决了。在构造函数上填上另外两个属性就好了。
public Message(String content, String start, String end) {
this.content = content;
this.start = start;
this.end = end;
}
成功反序列化!然后在将字段换回Boolean
类型:
问题成功解决!
fastjson反序列化
从上面我们可以猜测到,fastjson
在反序列化的时候,与构造函数是有关的,但是具体的关系,我们还不清楚。所以继续学习一下。
这里我们再添加一个构造函数,构造函数的参数只有两个:
public Message(String content, Boolean start, Boolean end) {
System.out.println("三个参数的构造函数");
this.content = content;
this.start = start;
this.end = end;
}
public Message(String content, Boolean start) {
System.out.println("两个参数的构造函数");
this.content = content;
this.start = start;
}
然后我们调用的是三个参数的构造函数:
再用两个和一个参数的构造函数测试:
public Message(String content, Boolean start) {
System.out.println("两个参数的构造函数");
this.content = content;
this.start = start;
}
public Message(Boolean start) {
System.out.println("一个参数的构造函数");
this.start = start;
}
所以从这里看,反序列化会选择参数较多的构造函数。
然后再添加一个无参的构造函数:
public Message(String content, Boolean start, Boolean end) {
System.out.println("三个参数的构造函数");
this.content = content;
this.start = start;
this.end = end;
}
public Message() {
System.out.println("无参构造");
}
然后有无参数的构造函数的时候,会直接调用无参的构造函数。
综上:
1.当没有无参的构造函数时,调用参数较多的构造函数
2.当有无参构造函数时,调用无参构造函数
所以:我们在涉及反序列化的时候,直接先写一个无参构造函数。
总结
有时候我们最开始认为的问题,并不是真正的问题所在,但是这并不能影响我们解决问题。按着步骤一步一步走,就会帮我们排除问题,最终慢慢找到问题所在。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。