1、概述
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,我们最常使用它来进行客户端-服务器通信。它既易于读/写又与语言无关。JSON 值可以是另一个 JSON对象、数组、数字、字符串、布尔值(true/false) 或null。
在本教程中,我们将了解如何使用可用的 JSON 处理库之一——JSON -Java库,也称为org.json来创建、操作和解析 JSON 。
进一步阅读:
2. 先决条件
我们首先需要在pom.xml中添加以下依赖项:
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20180130</version>
</dependency>
最新版本可以在Maven 中央存储库中找到。
请注意,这个包已经包含在 Android SDK 中,所以我们不应该在使用它时包含它。
3. Java 中的 JSON [包 org.json]
JSON-Java库也称为org.json(不要与 Google 的org.json.simple混淆)为我们提供了用于在 Java 中解析和操作 JSON 的类。
此外,该库还可以在 JSON、XML、HTTP 标头、Cookie、逗号分隔列表或文本等之间进行转换。
在本教程中,我们将了解以下类:
- JSONObject – 类似于 Java 的原生Map类对象,存储无序键值对
- JSONArray – 一个有序的值序列,类似于 Java 的原生 Vector 实现
- JSONTokener – 一种将一段文本分解为一系列标记的工具, JSONObject或JSONArray可以使用这些来解析 JSON 字符串
- CDL – 一种工具,提供将逗号分隔的文本转换为JSONArray的方法,反之亦然
- Cookie – 从 JSON字符串转换为 cookie,反之亦然
- HTTP – 用于从 JSON字符串转换为 HTTP 标头,反之亦然
- JSONException – 此库抛出的标准异常
4. JSON对象
JSONObject 是键值对的无序集合,类似于 Java 的原生Map实现。
- 键是不能为null的唯一字符串。
- 值可以是任何东西,从Boolean、Number、String或JSONArray到甚至JSONObject.NULL对象。
- JSONObject可以用大括号括起来的字符串表示,其中键和值用冒号分隔,对用逗号分隔。
- 它有几个构造函数来构造JSONObject。
它还支持以下主要方法:
- get(String key) – 获取与提供的键关联的对象,如果找不到键则抛出JSONException
- opt(String key) – 获取与提供的键关联的对象,否则为null
- put(String key, Object value) –在当前JSONObject中插入或替换键值对。
put()方法是一个重载方法,它接受String类型的键和值的多种类型。
有关JSONObject支持的方法的完整列表,请访问官方文档。
现在让我们讨论这个类支持的一些主要操作。
4.1。直接从JSONObject创建 JSON
JSONObject公开了一个类似于 Java 的Map接口的 API 。
我们可以使用put()方法并提供键和值作为参数:
JSONObject jo = new JSONObject();
jo.put("name", "jon doe");
jo.put("age", "22");
jo.put("city", "chicago");
现在我们的JSONObject看起来像这样:
{"city":"chicago","name":"jon doe","age":"22"}
JSONObject.put()方法有七种不同的重载签名。虽然键只能是唯一的非空字符串,但值可以是任何东西。
4.2. 从地图创建 JSON
我们可以构造一个自定义Map,然后将其作为参数传递给JSONObject的构造函数,而不是直接将键和值放入JSONObject中。
此示例将产生与上述相同的结果:
Map<String, String> map = new HashMap<>();
map.put("name", "jon doe");
map.put("age", "22");
map.put("city", "chicago");
JSONObject jo = new JSONObject(map);
4.3. 从 JSON字符串创建JSONObject
要将 JSON String解析为JSONObject,我们只需将String传递给构造函数即可。
此示例将产生与上述相同的结果:
JSONObject jo = new JSONObject(
"{\"city\":\"chicago\",\"name\":\"jon doe\",\"age\":\"22\"}"
);
传递的String参数必须是有效的 JSON;否则,此构造函数可能会抛出JSONException。
4.4. 将 Java 对象序列化为 JSON
JSONObject的构造函数之一将 POJO 作为其参数。在下面的示例中,包使用来自DemoBean类的 getter 并为其创建适当的JSONObject。
要从 Java 对象中获取JSONObject,我们必须使用一个有效的Java Bean类:
DemoBean demo = new DemoBean();
demo.setId(1);
demo.setName("lorem ipsum");
demo.setActive(true);
JSONObject jo = new JSONObject(demo);
这是JSONObject jo:
{"name":"lorem ipsum","active":true,"id":1}
尽管我们有办法将 Java 对象序列化为 JSON 字符串,但无法使用此库将其转换回来。如果我们想要那种灵活性,我们可以切换到其他库,例如Jackson。
5. JSON数组
JSONArray是一个有序的值集合,类似于 Java 的原生Vector实现。
- 值可以是Number、String、Boolean、JSONArray或JSONObject甚至是JSONObject.NULL对象。
- 它由用方括号括起来的字符串表示,由逗号分隔的值集合组成。
- 像JSONObject一样,它有一个构造函数,它接受一个源String并解析它以构造一个JSONArray。
这些是JSONArray类的主要方法:
- get(int index) – 返回指定索引处的值(介于 0 和总长度 - 1 之间),否则抛出JSONException
- opt(int index) – 返回与索引关联的值(介于 0 和总长度 - 1 之间)。如果该索引处没有值,则返回null。
- put(Object value) – 将一个对象值附加到此JSONArray。此方法是重载的,并且支持广泛的数据类型。
有关 JSONArray 支持的方法的完整列表,请访问官方文档。
5.1。创建JSONArray
初始化 JSONArray 对象后,我们可以使用put()和get()方法简单地添加和检索元素:
JSONArray ja = new JSONArray();
ja.put(Boolean.TRUE);
ja.put("lorem ipsum");
JSONObject jo = new JSONObject();
jo.put("name", "jon doe");
jo.put("age", "22");
jo.put("city", "chicago");
ja.put(jo);
以下是我们JSONArray的内容(为清晰起见,代码已格式化):
[
true,
"lorem ipsum",
{
"city": "chicago",
"name": "jon doe",
"age": "22"
}
]
5.2. 直接从 JSON 字符串创建JSONArray
与JSONObject一样,JSONArray也有一个构造函数,可以直接从 JSON String创建 Java 对象:
JSONArray ja = new JSONArray("[true, \"lorem ipsum\", 215]");
如果源String不是有效的 JSON String ,则此构造函数可能会抛出JSONException。
5.3. 直接从集合或数组创建JSONArray
JSONArray的构造函数也支持集合和数组对象作为参数。
我们只需将它们作为参数传递给构造函数,它将返回一个JSONArray对象:
List<String> list = new ArrayList<>();
list.add("California");
list.add("Texas");
list.add("Hawaii");
list.add("Alaska");
JSONArray ja = new JSONArray(list);
现在我们的JSONArray包含以下内容:
["California","Texas","Hawaii","Alaska"]
6. JSONTokener
JSONTokener将源字符串作为其构造函数的输入,并从中提取字符和标记。此包的类(如JSONObject、JSONArray)在内部使用它来解析 JSON Strings。
可能不会有很多情况下我们会直接使用这个类,因为我们可以使用其他更简单的方法(如string.toCharArray())实现相同的功能:
JSONTokener jt = new JSONTokener("lorem");
while(jt.more()) {
Log.info(jt.next());
}
现在我们可以像迭代器一样访问JSONTokener ,使用more()方法检查是否还有剩余元素,使用next()方法访问下一个元素。
以下是从上一个示例中收到的令牌:
l
o
r
e
m
7. CDL
我们提供了一个CDL(逗号分隔列表)类,用于将逗号分隔的文本转换为JSONArray,反之亦然。
7.1。直接从逗号分隔文本生成JSONArray
为了直接从逗号分隔的文本中生成JSONArray ,我们可以使用静态方法rowToJSONArray(),它接受JSONTokener:
JSONArray ja = CDL.rowToJSONArray(new JSONTokener("England, USA, Canada"));
这是我们的JSONArray现在包含的内容:
["England","USA","Canada"]
7.2. 从 JSONArray 生成逗号分隔的文本
让我们看看如何反转上一步并从JSONArray取回逗号分隔的文本:
JSONArray ja = new JSONArray("[\"England\",\"USA\",\"Canada\"]");
String cdt = CDL.rowToString(ja);
String cdt现在包含以下内容:
England,USA,Canada
7.3. 使用逗号分隔文本生成JSONObject的JSONArray
要生成JSONObject的JSONArray,我们将使用包含标头和数据的文本字符串,以逗号分隔。
我们使用回车符(\r)或换行符(\n) 分隔不同的行。
第一行被解释为标题列表,所有后续行都被视为数据:
String string = "name, city, age \n" +
"john, chicago, 22 \n" +
"gary, florida, 35 \n" +
"sal, vegas, 18";
JSONArray result = CDL.toJSONArray(string);
对象JSONArray 结果现在包含以下内容(为清楚起见,输出格式):
[
{
"name": "john",
"city": "chicago",
"age": "22"
},
{
"name": "gary",
"city": "florida",
"age": "35"
},
{
"name": "sal",
"city": "vegas",
"age": "18"
}
]
请注意,数据和标头都在同一个String中提供。我们有另一种方法来做到这一点,我们可以通过提供一个JSONArray 来获取标题和一个逗号分隔的字符串作为数据来实现相同的功能。
同样,我们使用回车符(\r)或换行符(\n)分隔不同的行:
JSONArray ja = new JSONArray();
ja.put("name");
ja.put("city");
ja.put("age");
String string = "john, chicago, 22 \n"
+ "gary, florida, 35 \n"
+ "sal, vegas, 18";
JSONArray result = CDL.toJSONArray(ja, string);
在这里,我们将完全像以前一样获取对象结果的内容。
8. 饼干
Cookie类处理 Web 浏览器 cookie,并具有将浏览器 cookie 转换为JSONObject的方法,反之亦然。
以下是Cookie类的主要方法:
- toJsonObject(String sourceCookie) –将 cookie 字符串转换为JSONObject
- toString(JSONObject jo) – 与上一个方法相反,将JSONObject转换为 cookie字符串
8.1。将 Cookie字符串转换为JSONObject
要将 cookie String转换为JSONObject,我们将使用静态方法Cookie.toJSONObject():
String cookie = "username=John Doe; expires=Thu, 18 Dec 2013 12:00:00 UTC; path=/";
JSONObject cookieJO = Cookie.toJSONObject(cookie);
8.2. 将JSONObject转换为 Cookie字符串
现在我们将JSONObject转换为 cookie String。这与上一步相反:
String cookie = Cookie.toString(cookieJO);
9. HTTP
HTTP类包含用于将 HTTP 标头转换为JSONObject的静态方法,反之亦然。
这个类还有两个主要方法:
- toJsonObject(String sourceHttpHeader) –将HttpHeader 字符串转换为JSONObject
- toString(JSONObject jo) – 将提供的JSONObject转换为String
9.1。将JSONObject转换为 HTTP 标头
HTTP.toString()方法用于将JSONObject转换为 HTTP 标头String:
JSONObject jo = new JSONObject();
jo.put("Method", "POST");
jo.put("Request-URI", "http://www.example.com/");
jo.put("HTTP-Version", "HTTP/1.1");
String httpStr = HTTP.toString(jo);
这是我们的String httpStr将包含的内容:
POST "http://www.example.com/" HTTP/1.1
请注意,在转换 HTTP 请求标头时,JSONObject必须包含“Method”、“Request-URI”和“HTTP-Version”键。对于响应头,对象必须包含“HTTP-Version”、“Status-Code”和“Reason-Phrase”参数。
9.2. 将 HTTP 标头字符串转换回JSONObject
在这里,我们将在上一步中获得的 HTTP 字符串转换回我们在该步骤中创建的JSONObject:
JSONObject obj = HTTP.toJSONObject("POST \"http://www.example.com/\" HTTP/1.1");
10. JSON异常
JSONException是这个包在遇到任何错误时抛出的标准异常。
这用于此包中的所有类。异常之后通常会出现一条消息,说明究竟出了什么问题。
11. 结论
在本文中,我们研究了一个使用 Java 的 JSON — org.json — 我们专注于这里提供的一些核心功能。
本文中使用的完整代码片段可以在 GitHub 上找到。