如何在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實(shí)現(xiàn)字符串倒序輸出的四種方法匯總
這篇文章主要介紹了Java實(shí)現(xiàn)字符串倒序輸出的四種方法匯總,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06
關(guān)于Java中BeanMap進(jìn)行對(duì)象與Map的相互轉(zhuǎn)換問(wèn)題
這篇文章主要介紹了利用BeanMap進(jìn)行對(duì)象與Map的相互轉(zhuǎn)換,通過(guò)net.sf.cglib.beans.BeanMap類(lèi)中的方法來(lái)轉(zhuǎn)換,效率極高,本文給大家分享實(shí)現(xiàn)代碼,感興趣的朋友一起看看吧2022-03-03
Mybatis有查詢(xún)結(jié)果但存不進(jìn)實(shí)體類(lèi)的解決方案
這篇文章主要介紹了Mybatis有查詢(xún)結(jié)果但存不進(jìn)實(shí)體類(lèi)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-11-11
Java開(kāi)發(fā)者進(jìn)行線上問(wèn)題排查的50個(gè)常用命令推薦
在生產(chǎn)環(huán)境中,當(dāng)Java應(yīng)用出現(xiàn)性能下降、響應(yīng)緩慢、內(nèi)存泄漏或崩潰等問(wèn)題時(shí),快速有效的問(wèn)題排查至關(guān)重要,本文匯總了50個(gè)最常用的命令,有需要的可以了解一下2025-05-05
java 數(shù)據(jù)結(jié)構(gòu)基本算法希爾排序
這篇文章主要介紹了數(shù)據(jù)結(jié)構(gòu)基本算法希爾排序的相關(guān)資料,需要的朋友可以參考下2017-08-08
spring中定時(shí)任務(wù)taskScheduler的詳細(xì)介紹
這篇文章主要介紹了spring中定時(shí)任務(wù)taskScheduler的相關(guān)資料,文中通過(guò)示例代碼介紹的很詳細(xì),相信對(duì)大家具有一定的參考價(jià)值,有需要的朋友們下面來(lái)一起看看吧。2017-02-02
Java基于命令模式實(shí)現(xiàn)郵局發(fā)信功能詳解
這篇文章主要介紹了Java基于命令模式實(shí)現(xiàn)郵局發(fā)信功能,較為詳細(xì)的分析了命令行模式的概念、原理并結(jié)合實(shí)例形式分析了Java使用命令行模式實(shí)現(xiàn)郵局發(fā)信功能的相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下2018-04-04
Java多線程實(shí)現(xiàn)之線程調(diào)度的使用
Java多線程中線程調(diào)度是一個(gè)核心概念,它決定了線程如何獲得CPU資源并執(zhí)行,合理的線程調(diào)度策略能夠充分發(fā)揮多核處理器的性能,提高程序的執(zhí)行效率,本文介紹了Java線程調(diào)度的原理、機(jī)制及相關(guān)的API,感興趣的可以了解一下2025-12-12
java實(shí)現(xiàn)網(wǎng)頁(yè)爬蟲(chóng)的示例講解
下面小編就為大家?guī)?lái)一篇java實(shí)現(xiàn)網(wǎng)頁(yè)爬蟲(chóng)的示例講解。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-08-08

