Java 与 JSON

JSON(JavaScript Object Notation)是一种基于文本的数据交换格式。几乎所有的编程语言都有很好的库或第三方工具来提供基于 JSON 的 API 支持,因此你可以非常方便地使用任何自己喜欢的编程语言来处理 JSON 数据。

本文主要从 Java 语言的角度来讲解 JSON 的应用。

1. JSON 简介

JSON 是什么

JSON 起源于 1999 年的 JS 语言规范 ECMA262 的一个子集(即 15.12 章节描述了格式与解析),后来 2003 年作为一个数据格式ECMA404(很囧的序号有不有?)发布。 2006 年,作为 rfc4627 发布,这时规范增加到 18 页,去掉没用的部分,十页不到。

JSON 的应用很广泛,这里有超过 100 种语言下的 JSON 库:json.org

更多的可以参考这里,关于 json 的一切

优缺点、标准与 schema

结构与类型

这估计是最简单标准规范之一:

  • 只有两种结构:对象内的键值对集合结构和数组,对象用 {} 表示、内部是”key”:”value”,数组用 [] 表示,不同值用逗号分开

  • 基本数值有 7 个: false / null / true / object / array / number / string

  • 再加上结构可以嵌套,进而可以用来表达复杂的数据

  • 一个简单实例:

扩展阅读:

2.2 优点

  • 基于纯文本,所以对于人类阅读是很友好的。

  • 规范简单,所以容易处理,开箱即用,特别是 JS 类的 ECMA 脚本里是内建支持的,可以直接作为对象使用。

  • 平台无关性,因为类型和结构都是平台无关的,而且好处理,容易实现不同语言的处理类库,可以作为多个不同异构系统之间的数据传输格式协议,特别是在 HTTP/REST 下的数据格式。

2.3 缺点

缺点也很明显:

  • 性能一般,文本表示的数据一般来说比二进制大得多,在数据传输上和解析处理上都要更影响性能。

  • 缺乏 schema,跟同是文本数据格式的 XML 比,在类型的严格性和丰富性上要差很多。XML 可以借由 XSD 或 DTD 来定义复杂的格式,并由此来验证 XML 文档是否符合格式要求,甚至进一步的,可以基于 XSD 来生成具体语言的操作代码,例如 apache xmlbeans。并且这些工具组合到一起,形成一套庞大的生态,例如基于 XML 可以实现 SOAP 和 WSDL,一系列的 ws-*规范。但是我们也可以看到 JSON 在缺乏规范的情况下,实际上有更大一些的灵活性,特别是近年来 REST 的快速发展,已经有一些 schema 相关的发展(例如理解 JSON Schema使用 JSON Schema在线 schema 测试),也有类似于 WSDL 的WADL出现。

相关技术以及与 XML 的关系

  • 使用 JSON 实现 RPC(类似 XML-RPC):JSON-RPC

  • 使用 JSON 实现 path 查询操作(类似 XML-PATH):JsonPATH

  • 在线查询工具:JsonPATH

工具

1.2. Java JSON 库

Java 中比较流行的 JSON 库有:

  • Fastjson - 阿里巴巴开发的 JSON 库,性能十分优秀。

  • Jackson - 社区十分活跃且更新速度很快。Spring 框架默认 JSON 库。

  • Gson - 谷歌开发的 JSON 库,目前功能最全的 JSON 库 。

从性能上来看,一般情况下:Fastjson > Jackson > Gson

JSON 编码指南

4.1 Google JSON 风格指南

遵循好的设计与编码风格,能提前解决 80%的问题:

简单摘录如下:

  • 属性名和值都是用双引号,不要把注释写到对象里面,对象数据要简洁

  • 不要随意结构化分组对象,推荐是用扁平化方式,层次不要太复杂

  • 命名方式要有意义,比如单复数表示

  • 驼峰式命名,遵循 Bean 规范

  • 使用版本来控制变更冲突

  • 对于一些关键字,不要拿来做 key

  • 如果一个属性是可选的或者包含空值或 null 值,考虑从 JSON 中去掉该属性,除非它的存在有很强的语义原因

  • 序列化枚举类型时,使用 name 而不是 value

  • 日期要用标准格式处理

  • 设计好通用的分页参数

  • 设计好异常处理

4.2 使用 JSON 实现 API

JSON API与 Google JSON 风格指南有很多可以相互参照之处。

JSON API是数据交互规范,用以定义客户端如何获取与修改资源,以及服务器如何响应对应请求。

JSON API 设计用来最小化请求的数量,以及客户端与服务器间传输的数据量。在高效实现的同时,无需牺牲可读性、灵活性和可发现性。

2. Fastjson 应用

扩展阅读:更多 API 使用细节可以参考:JSONField 用法

2.1. 添加 maven 依赖

2.2. Fastjson API

定义 Bean

Group.java

User.java

初始化 Bean

序列化

反序列化

2.3. Fastjson 注解

@JSONField

扩展阅读:更多 API 使用细节可以参考:JSONField 用法,这里介绍基本用法。

可以配置在属性(setter、getter)和字段(必须是 public field)上。

@JSONType

JSONType.alphabetic 属性: fastjson 缺省时会使用字母序序列化,如果你是希望按照 java fields/getters 的自然顺序序列化,可以配置 JSONType.alphabetic,使用方法如下:

3. Jackson 应用

扩展阅读:更多 API 使用细节可以参考 jackson-databind 官方说明

3.1. 添加 maven 依赖

3.2. Jackson API

序列化

反序列化

容器的序列化和反序列化

3.3. Jackson 注解

扩展阅读:更多注解使用细节可以参考 jackson-annotations 官方说明

@JsonProperty

@JsonIgnoreProperties@JsonIgnore

@JsonCreator

@JsonPropertyOrder

alphabetic 设为 true 表示,json 字段按自然顺序排列,默认为 false。

4. Gson 应用

详细内容可以参考官方文档:Gson 用户指南

4.1. 添加 maven 依赖

4.2. Gson API

序列化

反序列化

GsonBuilder

Gson 实例可以通过 GsonBuilder 来定制实例化,以控制其序列化、反序列化行为。

4.3. Gson 注解

@Since

@Since 用于控制对象的序列化版本。示例:

@SerializedName

@SerializedName 用于将类成员按照指定名称序列化、反序列化。示例:

5. 示例源码

示例源码:javalib-io-json

6. 参考资料

Last updated

Was this helpful?