fastjson 反序列化的问题

问题描述

Message对象序列化后,反序列化失败。java

clipboard.png

response是序列化的结果,starttrueendfalsejson

message是反序列化后的对象,startend都为false。函数

问题解决

1.资料查找

通过本身的初步debug后,并无任何的头绪,因此google了一下网上的解决办法。学习

由于content正确反序列化了,因此认为是boolean的问题,就去查关于反序列化布尔值的文章。测试

然而大面积都是相似下面这种标题的文章:this

clipboard.png

好像跟个人问题有点不一样,可是仍是抱着借鉴的心态看了几篇。结果如预期,并无什么用。可是从其中一片发现booleanBoolean在反序列化时的处理有点不一样。因此开始进行尝试。google

2.初步尝试

clipboard.png

这是一开始我实体中的字段设置,startend都是基本类型。spa

而后将他们改为封装类型Boolean,再来看一下结果:debug

clipboard.png

startend变成了null,依然失败。code

而后官方也提到了,boolean默认为false,而Boolean默认为null。也就是说,引发上面问题的缘由是在反序列化的时候,startend两个属性没有值。

3.再次尝试

又查了几篇相关的文章后,依然没有解决问题。因此想干脆使用String算了,进行字符传递。

clipboard.png

clipboard.png

然而,依然失败。可是既然一样是String类型的,content可以成功反序列化,为何startend就不行呢?

而后就开始了找不一样。发现了问题的所在。

clipboard.png

这里我写了一个本身的构造函数,可是参数只有content,而没有另外的参数。

4.问题解决

找到了不一样以后,问题就好解决了。在构造函数上填上另外两个属性就行了。

public Message(String content, String start, String end) {
    this.content = content;
    this.start = start;
    this.end = end;
}

clipboard.png

成功反序列化!而后在将字段换回Boolean类型:

clipboard.png

问题成功解决!

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;
}

而后咱们调用的是三个参数的构造函数:

clipboard.png

再用两个和一个参数的构造函数测试:

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;
}

clipboard.png

因此从这里看,反序列化会选择参数较多的构造函数。

而后再添加一个无参的构造函数:

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("无参构造");
}

clipboard.png

而后有无参数的构造函数的时候,会直接调用无参的构造函数。

综上:

1.当没有无参的构造函数时,调用参数较多的构造函数
2.当有无参构造函数时,调用无参构造函数

因此:咱们在涉及反序列化的时候,直接先写一个无参构造函数。

总结

有时候咱们最开始认为的问题,并非真正的问题所在,可是这并不能影响咱们解决问题。按着步骤一步一步走,就会帮咱们排除问题,最终慢慢找到问题所在。

相关文章
相关标签/搜索