在開發的過程當中,常常會碰到和本身預期不同的狀況。有的時候本身去研究一下仍是頗有趣的。這兩天在寫java web的時候,碰到了一個對象序列化的問題。java
public class AjaxJson {
private boolean success;
private String msg;
private Object obj;
private Map<String, Object> attributes;
//getter and setter
public String getJsonStr() {
JSONObject obj = new JSONObject();
obj.put("success", this.isSuccess());
obj.put("msg", this.getMsg());
obj.put("obj", this.obj);
obj.put("attributes", this.attributes);
return obj.toJSONString();
}
}
上面是一個接口類,咱們須要把這個類的對象序列化成json返回。那麼在springmvc中,通常是這樣操做的。web
@RequestMapping(params = "/get")
@ResponseBody
public AjaxJson del(HttpServletRequest request) {
AjaxJson json = new AjaxJson();
//省略業務操做
return json;
}
默認的話,返回ResponseBody
,對象會直接序列化成json。這個時候,咱們能夠看一下返回的json。spring
{
"success": "true",
"Msg":"1",
"obj":{
...
},
"attributes": null,
"jsonStr":"{"success": "true","Msg":"1","obj":{...},"attributes": null,}"
}
顯然,和咱們預期想的不太同樣,多了一個jsonstr字段。這個時候我在想,是否是springmvc的問題。結果仔細一想,springnvc之因此能夠直接將對象序列化成json,實際上是咱們添加的配置文件在起做用,真正參與序列化工做的是jackson這個庫。因而,我單獨使用了jackson,結果返回的json字符串和以前是相同的,這下就能夠確定是,jackson這個庫自己的設計問題了。json
帶着這份好奇,我把java中經常使用的json序列化的庫都試了一下,看看是否都是這樣。主流的庫有jackson、fastjson和gson。mvc
jackson和fastjson強依賴getter方法,底層試用反射。app
通過測試發現,jackson和阿里的fastjson返回的json字符串都帶有一個jsonstr字段,惟獨google的gson返回了咱們預期的結果——只序列化對象的field。測試
因而我找了下這幾個庫的序列化原理:fetch
因此,能夠看大咱們的AjaxJson類中存在這樣一個getJsonStr,所以,jsonStr就做爲key,序列化到json中了。this
固然在jackson中,提供了相應的annotation,能夠把這類方法忽略掉。在方法前加上@JsonIgnore
便可。google
private int mAge
的變量,而getter的方法是getAge()
。顯然咱們但願在序列化的時候獲得的key爲age而非mAge,那麼反射getter方法也就有它存在的意義了。