java常用JSON库注意事项总结
文章目录
如果想将对象进行网络传输,就需要序列话和反序列化。主要分为以文本为介质和以二进制为介质。以文本为介质最广泛的是 xml 和 json ,但是 xml 过于冗长,json 成为最常用的序列化反序列化的中间保存介质。以二进制方式保存的方式优点是速度快,数据量小,缺点是 human-unfriendly,目前比较流行的是 google 的 protobuf,比 java 原始序列化更快。
目前常用的json序列化反序列化类库有Jackson、Gson、Fastjson,其中Fastjson利用 ASM 框架,速度是这三者中最快的。速度的对比该项目做了详细的评测eishay/jvm-serializers,本文介绍下这三种 json 库在使用过程中需要注意的地方。
fastjson
-
字段命名问题 例如一个boolean成员变量isOnline,通过IDEA自动生成
getter:isOnline(),setter:setOnline(boolean online)
,我们期望序列化之后得到{"isOnline":true}
,但是实际是{"online":true}
,很容易解决,将getter写成isIsOnline()就可以了,同样的问题在Jackson中也存在,但在Gson中就没有。 -
null值的处理 默认情况下null变量不会写到json中(Gson也是如此) 如果想将null值写到json,需要启用
SerializerFeature.WriteMapNullValue
,此外还有其它对于null值的处理方式。 -
反序列化时为对象时,必须要有默认无参的构造函数,否则会报异常
com.alibaba.fastjson.JSONException: default constructor not found.
-
json数组反序列化实例
|
|
jackson
- 驼峰变量的转换
驼峰规范分为大驼峰(所有单词首字母大写)和小驼峰(除第一个单词其它单词首字母大写)我们在用jackson时,例如:
beFlag
和BeFlag
都会序列化为{"beFlag":null}
,但当变量名用一个大写字符作为大驼峰的第一个单词,例如BFlag
,我们期望转成json是为{"bFlag":null}
,实际情况是{"bflag":null}
,全部转换为小写。同样的在反序列化中bFlag
是不行的,应该和序列化出来的完全一致才行。
|
|
-
非public属性变量的处理 非public属性的变量不会进行序列化和反序列化,除非有getter和setter方法(Gson可以),当然我们的POJO一般都是private,通过getter、setter操作(fastjson也是如此)
-
静态变量不序列化
-
@JsonProperty声明在非public field会使之可以读到
-
加了@JsonProperty注解,默认是不做任何修改的字段名,也可以手动设置解析的名字
-
对象中的空属性会被序列化为null,例如:
{"beFlag":null}
,fastjson和Gson则不会。 -
json中如果设置某filed为字符串"null",反序列化后对象属性为null
-
字符类型的变量,json中传入ASCII,例如:
{"at":60}
或者{"at":"60"}
,jackson可以正常反序列化为'<'
,而Gson和Fastjson不可以,应该是jackson做了强制转换。 -
布尔字段问题,布尔字段不要以is开头,原因是根据javaBean的规范,字段
boolean isTest
的getter、setter方法分别是isIsTest()和setIsTest(),但是通常IDE自动生成或者lombok的方法分别是isTest()和setTest(),因此在反序列化的时候,jackson根据json中的字段推断出setter方法,例如反序列化{"isTest":true}
的时候,jackson会去找setIsTest()方法,但类中只有setTest方法,导致该字段没有设置。该问题fastjson也存在,gson中会兼容这种情况。 -
json数组反序列化示例
|
|
google-gson
-
默认情况下null变量不会写到json中
-
默认会开启 html 转义,可以通过
disableHtmlEscaping
禁用
|
|
- gson反序列化/序列化json的时候内存管理不是太好,引发较多gc。
- json中key的名字是java关键字,可以使用
@SerializedName
注释。 - json数组反序列化示例
|
|
其它
另外还有json-lib,flexjson,json-io,genson等不常用的库,这里不加分析。但他们的性能都没有上面介绍的三个常用的好,所以在实际应用中尽量不用考虑。