在开发的过程当中,常常会碰到和本身预期不同的状况。有的时候本身去研究一下仍是颇有趣的。这两天在写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方法也就有它存在的意义了。