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

问题重现

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中,一般是这样操作的。

@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方法也就有它存在的意义了。

参考文献

Json在序列化注意问题的更多相关文章

  1. [.net 面向对象程序设计进阶] (12) 序列化(Serialization)(四) 快速掌握JSON的序列化和反序列化

    [.net 面向对象程序设计进阶] (12) 序列化(Serialization)(四) 快速掌握JSON的序列化和反序列化 本节导读: 介绍JSON的结构,在JS中的使用.重点说明JSON如何在.N ...

  2. 在C#中,Json的序列化和反序列化的几种方式总结

    在这篇文章中,我们将会学到如何使用C#,来序列化对象成为Json格式的数据,以及如何反序列化Json数据到对象. 什么是JSON? JSON (JavaScript Object Notation) ...

  3. C#中的Json的序列化和反序列化

    Json是一种通用的数据格式,我们在数据交换的时候,经常会用到,下面介绍c#中的json序列化和反序列化,当然也可用在asp.net,silverlight,wpf中.我们在下面实例讲解如何进行Jso ...

  4. Json的序列化与反序列化

    对于Json的序列化和反序列化,如果自己编写源代码来实现的话,很复杂很烦,所以我采用的是使用别人已经写好的引用文件.这类文件网上有很多,我用的是LitJson,当然Newtonsoft也可以,但后者需 ...

  5. Newtonsoft.Json 的序列化与反序列化

    首先补充一点,Json.Net是支持序列化和反序列化DataTable,DataSet,Entity Framework和NHibernate的.我举例说明DataTable的序列化和反序列化.创建一 ...

  6. ASP.NET MVC 网站开发总结(六)——简谈Json的序列化与反序列化

    首先,先简单的谈一下什么是序列化与反序列化,序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程.在序列化期间,对象将其当前状态写入到临时或持久性存储区.以后,可以通 ...

  7. Asp.net中Json的序列化和反序列化(一)

    JSON是专门为浏览器中的网页上运行的JavaScript代码而设计的一种数据格式.在网站应用中使用JSON的场景越来越多,本文介绍ASP.NET中JSON的序列化和反序列化,主要对JSON的简单介绍 ...

  8. Atitit.json xml 序列化循环引用解决方案json

    Atitit.json xml 序列化循环引用解决方案json 1. 循环引用1 2. 序列化循环引用解决方法1 2.1. 自定义序列化器1 2.2. 排除策略1 2.3. 设置序列化层次,一般3级别 ...

  9. ASP.NET中JSON的序列化和反序列化

    JSON是专门为浏览器中的网页上运行的JavaScript代码而设计的一种数据格式.在网站应用中使用JSON的场景越来越多,本文介绍 ASP.NET中JSON的序列化和反序列化,主要对JSON的简单介 ...

  10. C# JSON字符串序列化与反序列化

    JSON与c#对象转换http://hi.baidu.com/donick/item/4d741338870c91fe97f88d33 C# JSON字符串序列化与反序列化 – http://www. ...

随机推荐

  1. Java开发笔记(一百五十一)Druid连接池的用法

    C3P0连接池自诞生以来在Java Web领域反响甚好,业已成为hibenate框架推荐的连接池.谁知人红是非多,C3P0在大型应用场合中暴露了越来越多的局限性,包括但不限于下列几点:1.C3P0管理 ...

  2. Codeforces Round #604 (Div. 2) (题解)

    A. Beautiful String (暴力) 题目链接 题目大意: 给定一个字符串,只有 \(?a\ b\ c\ ?\) ,问是否存在一种将所有的 \(?\) 替换成 \(a\ b\ c\) ,使 ...

  3. 深度学习-Wasserstein GAN论文理解笔记

    GAN存在问题 训练困难,G和D多次尝试没有稳定性,Loss无法知道能否优化,生成样本单一,改进方案靠暴力尝试 WGAN GAN的Loss函数选择不合适,使模型容易面临梯度消失,梯度不稳定,优化目标不 ...

  4. Mysql表字段命令alter add

    alter add命令用来增加表的字段. alter add命令格式:alter table 表名 add字段 类型 其他; 例如,在表MyClass中添加了一个字段passtest,类型为int(4 ...

  5. SSO实现机制

    引言 单点登录有许多开发商提供解决方案,本文以yale大学SSO开源项目CAS为例,介绍单点登录实现机制. 术语解释 SSO-Single Sign On,单点登录 TGT-Ticket Granti ...

  6. springboot项目,打包时携带所有依赖

    springboot项目,打包时携带所有依赖 本文主要解决springboot打包时,如何设置才能把当前项目的所有依赖都打进去. Springboot 的自带spring-boot-maven-plu ...

  7. tf.reduce_max的运用

    a=np.array([[[[1],[2],[3]],[[4],[25],[6]]],[[[27],[8],[99]],[[10],[11],[12]]],[[[13],[14],[15]],[[16 ...

  8. 【转载】 C#中使用float.Parse方法将字符串转换为Float类型

    在C#编程过程中,很多时候涉及到数据类型的转换,例如将字符串类型的变量转换为单精度Float类型就是一个常见的类型转换操作,float.Parse方法是C#中专门用来将字符串转换为float类型的,f ...

  9. Django:实现读写分离

    库的配置 1.读写分离 settings配置 #settings.py 配置库信息,生成2个库 DATABASES = { 'default': { 'ENGINE': 'django.db.back ...

  10. JavaScript中setInterval函数应用常见问题之一(第一个参数不加引号与加引号的区别)

    学过JavaScript 脚本语言的都应该接触过setInterval 函数.如何使用我想大家都知道,但是有时候对于刚刚接触JavaScript的朋友来讲,还是会在使用的时候碰到这样或那样的问题而感到 ...