Gson、FastJson、Jackson都是第三方序列化/反序列化 JSON格式的 Java库。JSON 是一种文本形式的数据交换格式,它比XML更轻量、比二进制容易阅读和编写,调式也更加方便。
介绍
Gson是Google提供的用来在Java对象和JSON数据之间进行映射的Java类库。Gson 最初是为在 Google 内部使用而创建的,后面进行了开源,Gson可以将一个Json字符转成一个Java对象,或者将一个Java转化为Json字符串。
关于性能和扩展性
以下是我们在运行许多其他东西以及测试的台式机(双 opteron、8GB RAM、64 位 Ubuntu)上获得的一些指标。您可以使用PerformanceTest类重新运行这些测试。
注意:删除disabled_前缀以运行这些测试。我们使用这个前缀来防止每次运行 junit 测试时运行这些测试。
使用 Gson
要使用的主要类是Gson,您可以通过调用 new Gson() 来创建它。还有一个类GsonBuilder可用于创建具有各种设置(如版本控制等)的 Gson 实例。
Gson 实例在调用 Json 操作时不维护任何状态。因此,您可以自由地为多个 Json 序列化和反序列化操作重用同一个对象。
Maven:
com.google.code.gson
gson
2.8.9
//创建方式一
Gson gson = new gson();
User obj= new User();
String json = gson.toJson(obj); //序列化user对象
User obj2 = gson.fromJson(json, User.class); //反序列化对象
//创建方式二
Gson gson = new GsonBuilder()
//序列化null
.serializeNulls()
// 设置日期时间格式,另有2个重载方法
// 在序列化和反序化时均生效
.setDateFormat("yyyy-MM-dd")
// 禁此序列化内部类
.disableInnerClassSerialization()
//生成不可执行的Json(多了 )]}' 这4个字符)
.generateNonExecutableJson()
//禁止转义html标签
.disableHtmlEscaping()
//格式化输出
.setPrettyPrinting()
.create();
User obj= new User();
String json = gson.toJson(obj); //序列化user对象
User obj2 = gson.fromJson(json, User.class); //反序列化对象
使用对象序列化优点
更多关于Gson的内容查看官网:https://sites.google.com/site/gson/gson-user-guide
介绍
fastjson是阿里巴巴的开源JSON解析库,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。
Maven:
com.alibaba
fastjson
x.x.x
其中 x.x.x 是版本号,根据需要使用特定版本,建议使用最新版本。
优点
fastjson相对其他JSON库的特点是快,从2011年fastjson发布1.1.x版本之后,其性能从未被其他Java实现的JSON库超越。
fastjson在阿里巴巴大规模使用,在数万台服务器上部署,fastjson在业界被广泛接受。在2012年被开源中国评选为最受欢迎的国产开源软件之一。
fastjson有非常多的testcase,在1.2.11版本中,testcase超过3321个。每次发布都会进行回归测试,保证质量稳定。
使用
User obj= new User();
//序列化对象
String json =JSON.toJSONString(obj);
//反序列化对象
User user=JSON.parseObject(json,User.class);
//反序列化集合方式一
List<User> res= JSON.parseArray(json,User.class);
//反序列化集合方式二
List<User> res6= JSON.parseObject(json,new TypeReference<List<User>>(){});
更多使用方式参考官方文档:https://github.com/alibaba/fastjson/wiki
漏洞
为了解决 在使用fastjson进行序列化的时候,会将子类型抹去,只保留接口(抽象类)的类型,使得反序列化时无法拿到原始类型,因此FastJson引入AutoType即在序列化的时候,把原始类型记录下来。后面带来的漏洞全与引入的AutoType特性有关。具体参看:https://zhuanlan.zhihu.com/p/157211675?from_voters_page=true
介绍
Jackson是一个简单的基于Java的库,用于将Java对象序列化为JSON,也可以把JSON转换为Java对象,是SpringBoot默认序列化Json库。
SpringBoot提供了 Jackson 的自动配置,spring-boot-starter-json
. 当自动配置好ObjectMapper
后会加载到类路径上。一些配置属性用于自定义 ObjectMapper.
下面表格为可配置项:
枚举类 | 属性 | 值 |
---|---|---|
com.fasterxml.jackson.databind.DeserializationFeature |
spring.jackson.deserialization. |
true , false |
com.fasterxml.jackson.core.JsonGenerator.Feature |
spring.jackson.generator. |
true , false |
com.fasterxml.jackson.databind.MapperFeature |
spring.jackson.mapper. |
true , false |
com.fasterxml.jackson.core.JsonParser.Feature |
spring.jackson.parser. |
true , false |
com.fasterxml.jackson.databind.SerializationFeature |
spring.jackson.serialization. |
true , false |
com.fasterxml.jackson.annotation.JsonInclude.Include |
spring.jackson.default-property-inclusion |
always , non_null , non_absent , non_default , non_empty |
特点
注解
@JsonFormat
: 实体类/属性使用的注解,在序列化或者反序列化的时候,指定属性格式化日期/时间。@JsonUnwrapped
: 作用在属性字段或方法上,用来将子JSON对象的属性添加到封闭的JSON对象。
@JsonView
该注解指明属性序列化和反序列时的视图级别(View)@JacksonInject
@JsonAnySetter
@JsonCreator
@JsonSetter
@JsonEnumDefaultValue
@JsonAnyGetter
@JsonGetter
@JsonPropertyOrder
@JsonRawValue
@JsonValue
@JsonRootName
@JsonSubTypes
@JsonTypeId
@JsonTypeInfo
@JsonTypeName
@JsonManagedReference
@JsonIdentityInfo
@JacksonAnnotation
@JacksonAnnotationsInside
官方文档:https://github.com/FasterXML/jackson-annotations/wiki/Jackson-Annotations
使用
ObjectMapper是JSON操作的核心,Jackson的所有JSON操作都是在ObjectMapper中实现。ObjectMapper有多个JSON序列化的方法,可以把JSON字符串保存File、OutputStream等不同的介质中。
基本方法
writeValue(File arg0, Object arg1)//把arg1转成json序列,并保存到arg0文件中。
writeValue(OutputStream arg0, Object arg1)//把arg1转成json序列,并保存到arg0输出流中。
writeValueAsBytes(Object arg0)//把arg0转成json序列,并把结果输出成字节数组。
使用实例
//POJO 转Json
User user=new User();
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(user);
user = mapper.readValue(json, User.class);
//Java集合转JSON
List<User> users = new ArrayList<User>();
users.add(user);
String jsonlist = mapper.writeValueAsString(users);
List<User> readValue = mapper.readValue(jsonList,new TypeReference<List<User>>(){});
性能
把Java对象JSON序列化,Jackson速度最快,在测试中比Gson快接近50%,FastJSON和Gson速度接近。
把JSON反序列化成Java对象,FastJSON、Jackson速度接近,Gson速度稍慢,不过差距很小。
性能方面,Jackson和FastJson差距很小,Jackson是SpringBoot默认的序列化库,也是最稳定的一个,FastJson由于频繁被曝出漏洞且作者没有那么多精力维护,所以默认序列方式还是选择Jackson最好。
参考资料
https://github.com/alibaba/fastjson/wiki
https://sites.google.com/site/gson/gson-user-guide
https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/reference/html/spring-boot-features.html#boot-features-json-jackson
https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/reference/html/howto.html#howto-customize-the-jackson-objectmapper
https://github.com/FasterXML/jackson-annotations/wiki/Jackson-Annotations
https://github.com/eishay/jvm-serializers/wiki