在Java Web开发的过程当中,时常会遇到与本身预期不同的状况。有的时候静下心来本身去研究一番内在的缘由仍是颇有趣的。这两天在写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
深刻探讨mvc
带着这份好奇,我把java中经常使用的json序列化的库都试了一下,看看是否都是这样。主流的库有jackson、fastjson和gson。app
通过测试发现,jackson和阿里的fastjson返回的json字符串都带有一个jsonstr字段,惟独google的gson返回了咱们预期的结果——只序列化对象的field。测试
因而我找了下这几个库的序列化原理:fetch
jackson和fastjsonthis
在序列化的时候,先利用反射找到对象类的全部get方法,接下来去get,而后小写化,做为json的每一个key值,而get方法的返回值做为value。接下来再反射field,添加到json中。google
gson
没有找到通俗的讲法,不过感受应该就和getter方法无关吧。
因此,能够看大咱们的AjaxJson类中存在这样一个getJsonStr,所以,jsonStr就做为key,序列化到json中了。
固然在jackson中,提供了相应的annotation,能够把这类方法忽略掉。在方法前加上@JsonIgnore 便可。
对此问题的理解
遇到问题的时候,千万不要忽略一些简单的地方,例如getter和setter方法。用getXXX的地方,能够用fetch等替代。
有时咱们会在类中定义例如private int mAge的变量,而getter的方法是getAge()。显然咱们但愿在序列化的时候获得的key为age而非mAge,那么反射getter方法也就有它存在的意义了。