如何在Java中使用org.json和JSON-B解析與編寫(xiě)JSON
前言
JSON(JavaScript Object Notation)因其輕量、語(yǔ)言無(wú)關(guān)且易于讀寫(xiě)的特性,已成為現(xiàn)代 Web 應(yīng)用中數(shù)據(jù)交換的標(biāo)準(zhǔn)格式。在 Java 中,處理 JSON 的庫(kù)眾多,其中 org.json 和 JSON-B 是兩種流行的選擇。本文將深入探討這兩種庫(kù)的特點(diǎn)、使用示例、優(yōu)缺點(diǎn)以及適用場(chǎng)景,幫助開(kāi)發(fā)者根據(jù)項(xiàng)目需求選擇合適的工具。
1. JSON 在 Java 中的重要性
JSON 是一種基于文本的數(shù)據(jù)格式,源自 JavaScript 編程語(yǔ)言(ECMA-262 第 3 版)。它支持兩種主要結(jié)構(gòu):
- 對(duì)象:鍵值對(duì)集合,通常用大括號(hào)
{}表示。 - 數(shù)組:有序值列表,用方括號(hào)
[]表示。
JSON 的簡(jiǎn)單性和跨語(yǔ)言兼容性使其成為 API 數(shù)據(jù)傳輸和配置文件存儲(chǔ)的理想選擇。在 Java 中,處理 JSON 需要專(zhuān)門(mén)的庫(kù)來(lái)解析 JSON 字符串并將其轉(zhuǎn)換為 Java 對(duì)象,或?qū)?Java 對(duì)象序列化為 JSON 字符串。本文將重點(diǎn)介紹 org.json 和 JSON-B 兩種庫(kù)。
2. org.json 概述
org.json(也稱(chēng)為 JSON-Java)是一個(gè)輕量級(jí)的 Java 庫(kù),廣泛用于 JSON 數(shù)據(jù)的解析和生成。它在 Android 開(kāi)發(fā)中尤為流行,因?yàn)樗?Android 平臺(tái)的默認(rèn) JSON 庫(kù)。該庫(kù)提供核心類(lèi)如 JSONObject 和 JSONArray,用于處理 JSON 對(duì)象和數(shù)組。
2.1 org.json 的特點(diǎn)
- 簡(jiǎn)單 API:易于上手,適合基本的 JSON 操作。
- 解析功能:支持從字符串、輸入流或讀取器解析 JSON。
- 序列化:允許從 Java 數(shù)據(jù)創(chuàng)建 JSON 對(duì)象和數(shù)組。
- 格式轉(zhuǎn)換:支持 JSON 與 XML、HTTP 頭、Cookie 等格式的轉(zhuǎn)換。
- 無(wú)依賴(lài):無(wú)需外部庫(kù),適合輕量級(jí)項(xiàng)目。
2.2 使用示例
以下是使用 org.json 解析和編寫(xiě) JSON 的示例代碼。
解析 JSON
以下代碼展示如何從 JSON 文件中讀取數(shù)據(jù)并提取特定字段:
public class SoftwareParseOrgJson {
final static String FILE_NAME = "/json/softwareinfo.json";
public static void main(String[] args) throws Exception {
InputStream jsonInput = SoftwareParseOrgJson.class.getResourceAsStream(FILE_NAME);
if (jsonInput == null) {
throw new NullPointerException("can't find" + FILE_NAME);
}
JSONObject obj = new JSONObject(new JSONTokener(jsonInput));
System.out.println("Software Name: " + obj.getString("name"));
System.out.println("Version: " + obj.getString("version"));
System.out.println("Description: " + obj.getString("description"));
System.out.println("Class: " + obj.getString("className"));
JSONArray contribs = obj.getJSONArray("contributors");
for (int i = 0; i < contribs.length(); i++) {
System.out.println("Contributor Name: " + contribs.get(i));
}
}
}
輸出:
Software Name: robinparse Version: 1.2.3 Description: Another Parser for JSON Class: RobinParse Contributor Name: Robin Smythe Contributor Name: Jon Jenz Contributor Name: Jan Ardann
此代碼通過(guò) JSONTokener 從輸入流創(chuàng)建 JSONObject,然后使用 getString 和 getJSONArray 方法提取字段。注意,JSONArray 不支持 Iterable,因此需要使用傳統(tǒng) for 循環(huán)遍歷。
編寫(xiě) JSON
以下代碼展示如何創(chuàng)建 JSON 對(duì)象并將其轉(zhuǎn)換為字符串:
.ConcurrentHashMap
public class WriteOrgJson {
public static void main(String[] args) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("Name", "robinParse")
.put("Version", "1.2.3")
.put("Class", "RobinParse");
String printable = jsonObject.toString();
System.out.println(printable);
}
}
輸出:
{"Name":"robinParse","Class":"RobinParse","Version":"1.2.3"}
此代碼利用 JSONObject 的流式 API(支持方法鏈?zhǔn)秸{(diào)用)添加鍵值對(duì),并通過(guò) toString 方法生成格式化的 JSON 字符串。
2.3 org.json 的優(yōu)缺點(diǎn)
| 優(yōu)點(diǎn) | 缺點(diǎn) |
|---|---|
| API 簡(jiǎn)單,易于快速上手 | 功能較少,缺乏高級(jí)映射支持 |
| 無(wú)外部依賴(lài),輕量級(jí) | 不如 Jackson 等庫(kù)強(qiáng)大 |
| 廣泛用于 Android 開(kāi)發(fā) | 定制化能力有限 |
3. JSON-B 概述
JSON-B(JSON Binding)是 Java API for JSON Binding(JSR-367),是 Jakarta EE 平臺(tái)的一部分。它旨在通過(guò)自動(dòng)映射簡(jiǎn)化 Java 對(duì)象與 JSON 數(shù)據(jù)之間的轉(zhuǎn)換。JSON-B 的參考實(shí)現(xiàn)是 Yasson,它還被納入 Eclipse MicroProfile 項(xiàng)目。
3.1 JSON-B 的特點(diǎn)
- 標(biāo)準(zhǔn) API:確??鐚?shí)現(xiàn)的可移植性。
- 自動(dòng)映射:無(wú)需手動(dòng)解析,支持 Java 對(duì)象與 JSON 的雙向轉(zhuǎn)換。
- 定制化:通過(guò)注解支持靈活的映射配置。
- 企業(yè)級(jí)支持:集成于 Jakarta EE,適合復(fù)雜應(yīng)用。
- 易用性:方法命名直觀,減少開(kāi)發(fā)工作量。
3.2 使用示例
以下是使用 JSON-B 讀取和編寫(xiě) JSON 的示例代碼。
讀取和編寫(xiě) JSON
以下代碼展示如何將 JSON 字符串轉(zhuǎn)換為 Java 對(duì)象并反向序列化:
public class ReadWriteJsonB {
public static void main(String[] args) throws IOException {
Jsonb jsonb = JsonbBuilder.create();
// 讀取
String jsonInput = "{\"id\":0,\"firstName\":\"Robin\",\"lastName\":\"Williams\"}";
Person rw = jsonb.fromJson(jsonInput, Person.class);
System.out.println(rw);
// 編寫(xiě)
String result = jsonb.toJson(rw);
System.out.println(result);
}
}
輸出(假設(shè) Person 類(lèi)有適當(dāng)?shù)?nbsp;toString 方法):
Person{id=0, firstName=Robin, lastName=Williams}
{"firstName":"Robin","id":0,"lastName":"Williams"}
此代碼通過(guò) JsonbBuilder 創(chuàng)建 Jsonb 實(shí)例,使用 fromJson 將 JSON 字符串轉(zhuǎn)換為 Person 對(duì)象,再通過(guò) toJson 將對(duì)象轉(zhuǎn)換回 JSON 字符串。默認(rèn)情況下,Person 類(lèi)無(wú)需注解即可工作。
定制化示例
JSON-B 支持通過(guò)注解定制映射。例如,排除冗余字段:
public class Person {
private int id;
private String firstName;
private String lastName;
@JsonbTransient
public String getFullName() {
return firstName + " " + lastName;
}
// getter 和 setter...
}
運(yùn)行上述代碼后,輸出將不包含 fullName 字段:
{"firstName":"Robin","id":0,"lastName":"Williams"}
通過(guò) @JsonbTransient 注解,getFullName 方法的返回值被排除在 JSON 輸出之外,從而減少數(shù)據(jù)冗余。
3.3 JSON-B 的優(yōu)缺點(diǎn)
| 優(yōu)點(diǎn) | 缺點(diǎn) |
|---|---|
| 標(biāo)準(zhǔn) API,跨平臺(tái)一致性 | 需要 Jakarta EE 環(huán)境 |
| 自動(dòng)映射,開(kāi)發(fā)效率高 | 對(duì)于簡(jiǎn)單任務(wù)可能過(guò)于復(fù)雜 |
| 支持高級(jí)定制化 | 依賴(lài)外部庫(kù) |
4. org.json 與 JSON-B 的比較
以下是對(duì) org.json 和 JSON-B 的詳細(xì)比較:
| 特性 | org.json | JSON-B |
|---|---|---|
| 標(biāo)準(zhǔn)化 | 非標(biāo)準(zhǔn),但廣泛使用 | 標(biāo)準(zhǔn) API(JSR-367) |
| 易用性 | 適合簡(jiǎn)單操作 | 自動(dòng)映射,開(kāi)發(fā)更高效 |
| 定制化 | 有限 | 通過(guò)注解支持廣泛定制 |
| 性能 | 適合中小型數(shù)據(jù) | 優(yōu)化用于大型數(shù)據(jù)集 |
| 依賴(lài) | 無(wú)需外部依賴(lài) | 需要 Jakarta EE 或類(lèi)似環(huán)境 |
| 適用場(chǎng)景 | 通用 JSON 解析/編寫(xiě) | Java 對(duì)象與 JSON 綁定 |
5. 適用場(chǎng)景
使用 org.json 的場(chǎng)景:
- 需要輕量級(jí)、無(wú)依賴(lài)的 JSON 處理庫(kù)。
- 在 Android 項(xiàng)目中進(jìn)行簡(jiǎn)單 JSON 操作。
- 項(xiàng)目對(duì)高級(jí)功能需求較低。
使用 JSON-B 的場(chǎng)景:
- 在 Jakarta EE 或 MicroProfile 環(huán)境中開(kāi)發(fā)企業(yè)級(jí)應(yīng)用。
- 需要標(biāo)準(zhǔn)化的 JSON 綁定 API。
- 項(xiàng)目要求復(fù)雜的對(duì)象映射和定制化。
6. 結(jié)論
org.json 和 JSON-B 都是 Java 中處理 JSON 的強(qiáng)大工具,各自適用于不同場(chǎng)景。org.json 因其簡(jiǎn)單性和無(wú)依賴(lài)特性,適合輕量級(jí)項(xiàng)目和 Android 開(kāi)發(fā);而 JSON-B 作為標(biāo)準(zhǔn) API,提供自動(dòng)映射和高級(jí)定制功能,適合企業(yè)級(jí)應(yīng)用。開(kāi)發(fā)者應(yīng)根據(jù)項(xiàng)目需求(如環(huán)境、復(fù)雜性和標(biāo)準(zhǔn)化要求)選擇合適的庫(kù)。
通過(guò)理解這兩種庫(kù)的優(yōu)缺點(diǎn),您可以為您的 Java 項(xiàng)目選擇最佳的 JSON 處理方案。
關(guān)鍵引用
- org.json GitHub 倉(cāng)庫(kù)
- JSON-B 官方規(guī)范
- Baeldung: JSON-Java 簡(jiǎn)介
- Baeldung: JSON Binding API 簡(jiǎn)介
到此這篇關(guān)于如何在Java中使用org.json和JSON-B解析與編寫(xiě)JSON的文章就介紹到這了,更多相關(guān)org.json和JSON-B解析JSON內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java對(duì)接阿里云短信服務(wù)保姆級(jí)教程(新手秒會(huì))
這篇文章主要介紹了如何在阿里云上申請(qǐng)短信服務(wù)以及如何使用Java代碼進(jìn)行對(duì)接,包括申請(qǐng)資質(zhì)、簽名和模板,以及編寫(xiě)Java代碼整合成工具類(lèi)進(jìn)行調(diào)用的步驟,需要的朋友可以參考下2024-12-12
SpringBoot Redis實(shí)現(xiàn)接口冪等性校驗(yàn)方法詳細(xì)講解
這篇文章主要介紹了SpringBoot Redis實(shí)現(xiàn)接口冪等性校驗(yàn)方法,近期一個(gè)老項(xiàng)目出現(xiàn)了接口冪等性校驗(yàn)問(wèn)題,前端加了按鈕置灰,依然被人拉著接口參數(shù)一頓輸出,還是重復(fù)調(diào)用了接口,通過(guò)復(fù)制粘貼,完成了后端接口冪等性調(diào)用校驗(yàn)2022-11-11
SpringBoot程序打包失敗(.jar中沒(méi)有主清單屬性)
在學(xué)習(xí)SpringBoot,打包SpringBoot程序后,在cmd運(yùn)行出現(xiàn)了 某某某.jar中沒(méi)有注清單屬性,本文就來(lái)介紹一下原因以及解決方法,感興趣的可以了解一下2023-06-06
面試題:Java 實(shí)現(xiàn)查找旋轉(zhuǎn)數(shù)組的最小數(shù)字
這篇文章主要介紹了Java 實(shí)現(xiàn)查找旋轉(zhuǎn)數(shù)組的最小數(shù)字,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-07-07
Java多線(xiàn)程之synchronized關(guān)鍵字的使用
這篇文章主要介紹了Java多線(xiàn)程之synchronized關(guān)鍵字的使用,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有非常好的幫助,需要的朋友可以參考下2021-04-04
springboot validator枚舉值校驗(yàn)功能實(shí)現(xiàn)
這篇文章主要介紹了springboot validator枚舉值校驗(yàn)功能實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01
淺析idea 添加項(xiàng)目依賴(lài)的兩種方式
這篇文章主要介紹了idea 添加項(xiàng)目依賴(lài)的兩種方式,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12

