您的位置:首頁>正文

Java中的Json序列化,不容忽視的getter

在開發的過程中, 經常會碰到和自己預期不一樣的情況。 有的時候自己去研究一下還是很有趣的。 這兩天在寫java web的時候, 碰到了一個物件序列化的問題。

問題重現public class AjaxJson { private boolean success; private String msg; private Object obj; private Map 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中, 一般是這樣操作的。

@RequestMapping(params = "/get") @ResponseBody public AjaxJson del(HttpServletRequest request) { AjaxJson json = new AjaxJson; //省略業務操作 return json; }

預設的話, 返回ResponseBody, 物件會直接序列化成json。 這個時候, 我們可以看一下返回的json。

{ "success": "true", "Msg":"1", "obj":{ ... }, "attributes": null, "jsonStr":"{"success": "true","Msg":"1","obj":{...},"attributes": null,}" }

顯然, 和我們預期想的不太一樣, 多了一個jsonstr欄位。 這個時候我在想, 是不是springmvc的問題。 結果仔細一想, springnvc之所以可以直接將物件序列化成json, 其實是我們添加的設定檔在起作用,

真正參與序列化工作的是jackson這個庫。 於是, 我單獨使用了jackson, 結果返回的json字串和之前是相同的, 這下就可以肯定是, jackson這個庫本身的設計問題了。

深入探討

帶著這份好奇, 我把java中常用的json序列化的庫都試了一下, 看看是否都是這樣。 主流的庫有jackson、fastjson和gson。

經過測試發現, jackson和阿裡的fastjson返回的json字串都帶有一個jsonstr欄位, 唯獨google的gson返回了我們預期的結果——只序列化物件的field。

於是我找了下這幾個庫的序列化原理:

jackson和fastjson
在序列化的時候, 先利用反射找到物件類的所有get方法, 接下來去get, 然後小寫化, 作為json的每個key值, 而get方法的返回值作為value。 接下來再反射field, 添加到json中。 gson
沒有找到通俗的講法, 不過感覺應該就和getter方法無關吧。

所以, 可以看大我們的AjaxJson類中存在這樣一個getJsonStr,

因此, jsonStr就作為key, 序列化到json中了。

當然在jackson中, 提供了相應的annotation, 可以把這類方法忽略掉。 在方法前加上@JsonIgnore即可。

個人理解 遇到問題的時候, 千萬不要忽略一些簡單的地方, 例如getter和setter方法。 同時也可以一定程度畢業用到getXXX, 可以用fetch等替代。 有時我們會在類中定義例如private int mAge的變數, 而getter的方法是getAge。 顯然我們希望在序列化的時候得到的key為age而非mAge, 那麼反射getter方法也就有它存在的意義了。

參考文獻 java中坑爹的getter、setter方法的潛規則Jackson學習筆記(三)FastJSON 原理剖析 以及 和 Jackson的對比 who is the most fast!]

同類文章
Next Article
喜欢就按个赞吧!!!
点击关闭提示