今天在項目中遇到控制器中返回的對象經過fastjsonMessageConverter轉換后,前台收到的json中多了一個字段A的問題。而返回的這個對象中根本就沒有定義這個字段A。
查了好久才發現對象中雖然沒有這個字段A,但是有個叫做isA()的方法。
原來fastjson在序列化時是根據方法來的,而不是根據字段來的!
既然找到了問題。那么自然就好解決了。可以為這個方法加上@JSONField(serialize=false),讓它不參與序列化。
其實最主要的還是在定義對象時,嚴格按照POJO的規范來。
不過既然出現了問題,我們不妨來測試一下fastjson的序列化的規則。
測試代碼:
package com.insanexs.fastjson; import com.alibaba.fastjson.JSON; public class Foo { //有set/get方法 private String prop1; //有操作概屬性的方法,但不是set/get方法 private String prop2; //沒有方法直接操作這個屬性,由構造函數傳入 private String prop3; private boolean prop4; public Foo(){ } public Foo(String prop1, String prop2, String prop3, boolean prop4){ this.prop1 = prop1; this.prop2 = prop2; this.prop3 = prop3; this.prop4 = prop4; } public String getProp1() { return prop1; } public void setProp1(String prop1) { this.prop1 = prop1; } public String popProp2(){ return prop2; } public void pushProp2(String prop2){ this.prop2 = prop2; } //增加了打印,便於了解調用了哪個函數 public boolean isProp4(){ System.out.println("invoke isProp4()"); return prop4; } public boolean getProp4(){ System.out.println("invoke getProp4()"); return prop4; } //沒有對應屬性,只有get方法 public String getProp5(){ return "4"; } //沒有對應屬性,有一個is方法 public boolean isProp6(){ return true; } public static void main(String[] args){ Foo f = new Foo("1","2","3", false); String text = JSON.toJSONString(f); System.out.println(text); } }
我們可以看到控制台的輸出是:
我們可以看到雖然對象有prop2和prop3,但是因為沒有對應的set/get方法,導致屬性沒有被序列化。而prop5和prop6雖然對象沒有直接定義這個屬性,但是因為有對應的方法,因此也被序列化輸出了。
對於同時存在isXX和getXX的屬性,get要先於is方法。如果我們注釋了get方法,會發現is方法被調用了。