Json常用序列化工具包大比拼

一、前言

Json已成为计算机编程中最常用的数据传输和存储格式之一,所以对Json的序列化和反序列化工具的选择也是互联网系统中比较重要的环节,尤其在高并发下的执行效率,可能会直接影响系统的吞吐率。本文将从功能和性能两方面对常用的四种Json处理工具进行对比,以便选出符合我们系统需要的Json处理工具。

二、功能对比

项目

json-lib

fastJson

Jackson

Gson

最新版本号

2.4

1.2.51

2.97

2.8.5

最后更新

2010/12/14

2018/9/30

2018/9/19

2018/5/22

被引用次数

426

1492

5185

8655

是否支持注解

No

Yes

Yes

Yes

Map中的key为Long时

报错

正常输出,不是标准格式

会把key转成String

会把key转成String

特殊字符

支持

支持

支持

支持

控制字符

支持

支持

支持

支持

表情字符

支持

支持

支持

支持

 

  从上表可以得出以下结论:

  1. Sf的json-lib已经很久没有更新了,其它三种都还一直在更新维护
  2. 从Maven库中被引用的次数来看,sf的json-lib也是使用的最少的,而Gson和Jackson被使用的较多
  3. 当对象中包含key为Long类型的Map时,json-lib序列化时会报错,fastJson是正常以整数作为key输出,Jackson和Gson会把key转换成字符串输出。fastJson的处理方式会导致反序列化报错
  4. 经测试,四个工具包对特殊字符的处理都没有问题

其它说明:

  1、 Jackson、json-lib反序列化时,要求所有涉及的Bean必须存在默认的构造函数

  2、 fastJson、json-lib反序列化,再序列化之后得到的JSON与之前可能不一致,因为Map的顺序会变,而Jackson、gson反序列化之后是一致的,其使用了LinkedHashMap保证顺序

  3、 fastJson、Gson输出json时会忽略值为null的字段;对于值为null的字段,jackson输出null,而json-lib输出空字符串

  4、 fastJson反序列化时,二级对象中的List出现过没有被反序列化的情况,但后来测试又可以反序列化了,目前还没有找到规律

 

三、性能对比

1) 序列化操作

第一组

测试环境:本地Windows、2核8G内存,64位OS

Bean对象:小对象,输出Json后约1.83KB

 

结论:

  1. 对于小对象的序列化,json-lib在高并发的情况下效率明显不如其它三个工具,同时json-lib的CPU占用率达到100%
  2. fastJson、Jackson和Gson对小对象的序列化执行效率差异不明显,但Jackson更优

第二组

测试环境:本地Windows、2核8G内存,64位OS

Bean对象:大对象,输出Json后约8.99KB

 

结论:

  1. 对于大对象,sf的json-lib执行效率明显不如其它三个工具。在高并发的情况下,Jackson的执行效率几乎是json-lib的10倍;
  2. Gson的执行效率也明显不如fastJson和Jackson,消耗时间几乎是它们的2倍;
  3. 执行效率上,Jackson优于fastJson
  4. Gson对CPU的占用率控制的最好,一直在80%左右

 

第三组

测试环境:本地Windows、2核8G内存,64位OS

Bean对象:特大对象,输出Json后约56.1KB。因在小对象测试中证明json-lib和gson在高并发下效率不好,所以大对象测试中忽略这两个包,只对比fastjson和jackson。

 

结论:

  1. 执行效率上,Jackson优于fastJson。网上很多朋友都说fastjson比jackson快,可能是使用了jackson1.x的缘故,后面有时间再测试一下。

 

2) 反序列化操作

第一组

测试环境:本地Windows、2核8G内存,64位OS

输入数据:小对象,输入Json约1.83KB

 

总结:

  1. 对于小文件的反序列化,json-lib效率明显不行
  2. 在高并发的情况下,Jackson的效率最优
  3. 对于小文件的反序列化操作,即使高并发的情况下,CPU占用率也表现比较平稳,相对来说fastJson的CPU占用率更高

 

第二组

       测试环境:本地Windows、2核8G内存,64位OS

输入数据:大对象,输入Json约9.83KB

 

结论:

  1. 对于大文件的反序列化,json-lib和Gson的执行效率明显不如fastJson和Jackson
  2. 高并发的情况下,Jackson的执行效率优于fastJson

 

第三组

测试环境:本地Windows、2核8G内存,64位OS

输入数据:特大对象,输入Json约56.1KB

 

结论:

  1. 对于更大文件的反序列化,json-lib和Gson的执行效率明显不如fastJson和Jackson
  2. Jackson的执行效率优于fastJson,尤其是高并发的情况下

 

四、总结

 经过以上测试及对比,基本可以得出结论:Jackson工具包(测试中使用2.9.5版本)在功能和性能方面都表现的更出色,在新开发系统时可以考虑使用Jackson进行JSON数据的处理。理由如下:

  1. Jackson使用广泛,并且仍然在持续更新
  2. Jackson对特殊字符支持完好
  3. 在序列化和反序列化时,Jackson的性能在测试的4个工具包中表现最优,尤其是对大文件或高并发时表现更好。

 

五、使用Jackson的注意事项

在使用Jackson时,有一些注意事项,需要在编写代码时注意,具体如下:

1)      反序列化时,要求所有涉及的Bean必须存在默认的构造函数,否则会报错;

2)      反序列化时,如果json中有部分字段是对象中不存在的属性,或对象中无get/set方法,会报“UnrecognizedPropertyException”,解决方法是:

  在类中添加 @JsonIgnoreProperties(ignoreUnknown = true),

  或者代码中设置:

  mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

3)      反序列化的类是抽象类或者接口,就会导致“Can not construct instance of”这个异常。

  解决方法:添加@JsonDeserialize(as = Cat.class)注解

  如下:

   

 

  Json文件:

  {"id":1001,"name":"布莱德","weight":1.67,"animal":{"color":"Blue"}}

 

4)      当反序列化的JSON中包含了单引号而不是双引号的时候,会抛“Unexpected character (''' (code 39))”异常,

如Json:{"id":1001,"name":'布莱德','weight':1.67, "feild1": 56}

解决方法:

  JsonFactory factory = new JsonFactory();

  factory.enable(JsonParser.Feature.ALLOW_SINGLE_QUOTES);

     ObjectMapper mapper = new ObjectMapper(factory);

 

六、Jackson从1.x迁移到2.x的步骤

1)      修改POM文件

旧依赖

新依赖

<dependency>

<groupId>org.codehaus.jackson</groupId>

<artifactId>jackson-mapper-asl</artifactId>

<version>1.x.x</version>

</dependency>

<dependency>

<groupId>com.fasterxml.jackson.core</groupId>

<artifactId>jackson-core</artifactId>

<version>2.9.5</version>

</dependency>

<dependency>

<groupId>com.fasterxml.jackson.core</groupId>

<artifactId>jackson-databind</artifactId>

<version>1.x.x</version>

</dependency>

<dependency>

<groupId>com.fasterxml.jackson.core</groupId>

<artifactId>jackson-databind</artifactId>

<version>2.9.5</version>

</dependency>

 

2)      包名更改

所有以org.codehaus.jackson开头的包名都替换成com.fasterxml.jackson开头的。

 

3)      设置属性的代码调整

  SerializationConfig.Feature.* 改成 SerializationFeature.*

  DeserializationConfig.Feature.* 改成 DeserializationFeature.*

      

posted @ 2018-12-20 20:55  轻架构  阅读(3083)  评论(2编辑  收藏  举报