fastjson 反序列化的問題

問題描述

Message對象序列化後,反序列化失敗。

clipboard.png

response是序列化的結果,starttrueendfalse

message是反序列化後的對象,startend都爲false。

問題解決

1.資料查找

經過自己的初步debug後,並沒有任何的頭緒,所以google了一下網上的解決辦法。

因爲content正確反序列化了,所以認爲是boolean的問題,就去查關於反序列化布爾值的文章。

然而大面積都是類似下面這種標題的文章:

clipboard.png

好像跟我的問題有點不同,但是還是抱着借鑑的心態看了幾篇。結果如預期,並沒有什麼用。但是從其中一片發現booleanBoolean在反序列化時的處理有點不同。所以開始進行嘗試。

2.初步嘗試

clipboard.png

這是一開始我實體中的字段設置,startend都是基本類型。

然後將他們改成封裝類型Boolean,再來看一下結果:

clipboard.png

startend變成了null,依然失敗。

然後官方也提到了,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.當有無參構造函數時,調用無參構造函數

所以:我們在涉及反序列化的時候,直接先寫一個無參構造函數。

總結

有時候我們最開始認爲的問題,並不是真正的問題所在,但是這並不能影響我們解決問題。按着步驟一步一步走,就會幫我們排除問題,最終慢慢找到問題所在。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章