活泼的网站,网站空间托管合同 .doc,自助友链平台,大连旅顺樱花在开发的过程中#xff0c;经常会碰到和自己预期不一样的情况。有的时候自己去研究一下还是很有趣的。这两天在写java web的时候#xff0c;碰到了一个对象序列化的问题。问题重现public class AjaxJson {private boolean success;private String msg;private Object obj;pri…在开发的过程中经常会碰到和自己预期不一样的情况。有的时候自己去研究一下还是很有趣的。这两天在写java web的时候碰到了一个对象序列化的问题。问题重现public class AjaxJson {private boolean success;private String msg;private Object obj;private Map attributes;//getter and setterpublic 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)ResponseBodypublic 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方法也就有它存在的意义了。参考文献