Android入行多年,用起JSON依然是捉襟见肘,无法手到擒来的感觉实在是让自己汗颜。于是决定把JSON从头到尾总结一遍。这里很多是根据网络上现有的资料进行的总结。
什么是JSON
JavaScrip Object Notation,JS对象标记,简写成JSON。
网络上无法直接传递结构复杂的数据,需要把这些复杂的结构转换为简单结构。JSON就是一套简单的格式规范,把复杂的数据结构转换成最简单的字符串。
在JSON之前,网络上大家使用XML的格式来传递数据。但是XML格式比较复杂,后来就出现了轻量化的JSON替代了XML。
JSON的字符集必须是utf-8。所以不存在跨平台的问题。
JSON只有6种数据类型:
- number: 数值,包括整型、浮点型
- string: 字符串
- boolean: 布尔值,true和false
- null: 等同于Java的null
- array: 数组
- object: JSON对象,它是以上五种类型的组合
JSON的构成规则:
- 数据在键值对中
- 数据用逗号隔开
- 花括号表示对象
- 方括号表示数组
- 双引号表示字符
- 键值对里的key用双引号包含
- 6种基本类型可以任意组合
JSON实例
{
"name" : "xiaoming",
"age" : 18,
"marriage" : false,
"nickname" : [ // 字符串数组
"ming",
"dong",
"zhuzi"
],
"bookList": [ // 对象数组
{"title" : "Pride and Prejudice", "price" : 20},
{"title" : "History of the America", "price" : 40}
]
}
数组里的值,可以是基本类型中的任意一种。bookList里是JSON object的列表(数组)。
Map在JSON里长什么样呢?不是array,是一个普通的object
{
"mapExample": {
"key1": "value1",
"key2": "value2",
"key3": "value3",
}
}
经典的状态机表示法
如何使用JSON
JSON的形态
JSON本质上是一串utf-8编码的符合Json格式的字符。『JSON』这个词,广义上是指这串字符及其用法;狭义上就是指这串字符。JSON的形态,描述的是狭义上,也就是JSON字符串的形态。对于我们这些需要去处理它的人来说,它存在两种状态:
- 静态的字符串
- 格式化后对应的数据结构
我们经常需要在这两种状态之间进行转换。比如,将某个数据结构转成JSON字符串;或者从某个JSON字符串中读取某个字段。从1到2的过程,称之为『进』;从2到1,称之为『出』。JSON的用法,就是围绕着这两个状态展开说明。
下面只介绍Java类库的JSON包和Google的Gson。
Java上的JSON包
org.json包,有以下几个主要类:
- JSONObject:它能够从JSON字符串中解析出里面的元数据;或者把元数据组装成JSON字符串。
- JSONArray:它是JSONObject的一个子集,只处理JSON array相关的数据。
- JSONTokener:
- JSONPointer
- JSONString
- JSONStringer
- JSONWriter
最常用的是JSONObject和JSONArray,它们能满足日常需求。这两者本身就是格式化后的数据结构的代表,存储的是格式化后的数据。下面只介绍这两个的用法,其它的以后有时间再展开。
JSONObject的进
JSONObject就是JSON基本里的Object,它只支持以花括号({})开头和结尾的字符串。它包含其它类型以及自己。它的『进』有两种方式:
- JSONObject的构造函数
- JSONObject的put方法
构造函数里传入符合JSON格式的字符串,得到格式化后的数据,例如:
new JSONObject(jsonStr);
put方法用来增加数据。它增加基本类型很直观,直接放进去就好了。Object类型需要注意。放进去的值是Object.toString后的值。所以如果是一个普通的Java的Object,那么值就是这个对象的类名(除非重写toString方法)。如果传入的是JSONObject或者JSONArray类型的Object,这两者的toString得到的值就是JSON字符串。
通过构造函数生成JSONObject后,还可以继续用put方法增加数据(新字段)和修改数据(原有字段)。
JSONObject是格式化后的结构,因此可以方便地取出其中的数据。
- get方法
- opt方法
两者的区别是,get方法会抛出异常,opt方法不会,并且可以使用默认值。
JSONObject的出
转换成静态的Json字符串,直接使用toString方法即可。
JSONArray的进和出
它支持各种基础类型。和JSONObject类似,每个接口多index参数,表示数组的位置。
Android上的Gson包
Gson是Google的Json处理工具。它提供了比Java的Json工具包更强大和方便的功能。它的基本使用,都集中在Gson.java这个类。为了不把两者混淆,后面用gson来表示Gson这个类。
Gson的适用性比JSONObject大,后者只支持标准格式的Json字符串。Gson可以支持单独的Json数据类型,比如:
int intValue = gson.fromJson("128", Integer.class); // intValue=128
Integer[] intArray = gson.fromJson("[1, 2, 4, 8, 16]", Integer[].class); // intArray=[1, 2, 4, 8, 16]
Gson的常规用法非常简单,所有的接口都集中在gson里。gson为一个入口,非常简洁,基本上只提供了两类方法,也就是『进』fromJson()和『出』toJson()。
gson的『进』
fromJson接口,从各种类型的源中直接生成所需要的数据结构。对比JSONObject,gson更方便。前者只是做了格式化,后者不但格式化,而且生成对应的数据结构对象(某个具体的数据对象)。
gson的『出』
toJson接口,从各种类型的格式化数据源,生成对应的JSON字符串。同样,对比JSONObject,gson可以直接将数据结构对象转成JSON字符串。前者只能手动从数据对象中一个字段一个字段地转成JSONObject,然后再转成JSON字符串。
Gson的数据类型
Gson把JSON的六种基本数据类型进行了封装。基类是JsonElement。string、number和boolean这三种基本类型统一为JsonPrimitive。还有JsonObject、JsonArray和JsonNull。
这部分的详细说明,后续再细化,本文会持续更新。
Gson的高级用法
Gson还有很多高级的用法,比如可添加adapter,用的比较少,以后另外看一篇介绍。