問題描述
將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.當有無參構造函數時,調用無參構造函數
所以:我們在涉及反序列化的時候,直接先寫一個無參構造函數。
總結
有時候我們最開始認爲的問題,並不是真正的問題所在,但是這並不能影響我們解決問題。按着步驟一步一步走,就會幫我們排除問題,最終慢慢找到問題所在。