Java 与 JSON

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

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

1. JSON 简介

JSON 是什么

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

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

更多的可以参考这里,关于 json 的一切arrow-up-right

优缺点、标准与 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 Schemaarrow-up-right使用 JSON Schemaarrow-up-right在线 schema 测试arrow-up-right),也有类似于 WSDL 的WADLarrow-up-right出现。

相关技术以及与 XML 的关系

工具

1.2. Java JSON 库

Java 中比较流行的 JSON 库有:

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

JSON 编码指南

4.1 Google JSON 风格指南

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

简单摘录如下:

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

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

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

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

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

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

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

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

  • 日期要用标准格式处理

  • 设计好通用的分页参数

  • 设计好异常处理

4.2 使用 JSON 实现 API

JSON APIarrow-up-right与 Google JSON 风格指南有很多可以相互参照之处。

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

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

2. Fastjson 应用

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

2.1. 添加 maven 依赖

2.2. Fastjson API

定义 Bean

Group.java

User.java

初始化 Bean

序列化

反序列化

2.3. Fastjson 注解

@JSONField

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

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

@JSONType

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

3. Jackson 应用

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

3.1. 添加 maven 依赖

3.2. Jackson API

序列化

反序列化

容器的序列化和反序列化

3.3. Jackson 注解

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

@JsonProperty

@JsonIgnoreProperties@JsonIgnore

@JsonCreator

@JsonPropertyOrder

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

4. Gson 应用

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

4.1. 添加 maven 依赖

4.2. Gson API

序列化

反序列化

GsonBuilder

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

4.3. Gson 注解

@Since

@Sincearrow-up-right 用于控制对象的序列化版本。示例:

@SerializedName

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

5. 示例源码

示例源码:javalib-io-jsonarrow-up-right

6. 参考资料

Last updated

Was this helpful?