知識庫 / JSON RSS 訂閱

JSON-Java (org.json) 簡介

JSON
HongKong
9
09:54 PM · Dec 05 ,2025

1. 概述

JSON(JavaScript Object Notation)是一種輕量級的數據交換格式,我們最常見地將其用於客户端與服務器之間的通信。 此外,它易於閲讀和編寫,並且與語言無關。一個 JSON 值可以是另一個 JSON 對象, 數組, 數字, 字符串, 布爾值(true/false)或 null

在本教程中,我們將學習如何使用 Java 中可用的 JSON 處理庫(即 JSON-Java 庫,也稱為 org.json)創建、操作和解析 JSON。

2. 先決條件

首先,我們需要在我們的 pom.xml 中添加以下依賴項:

<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20250517</version>
</dependency>

我們可以從 Maven Central 倉庫 獲取最新版本。

但是,在使用 Android SDK 時,我們無需顯式包含依賴項,因為它已經包含了該包。

3. Java 中的 JSON [org.json包]

我們使用來自 JSON-Java 庫的類來在 Java 中解析和操作 JSON。我們還將其稱為 org.json。但是,我們不應將其與 Google 的 org.json.simple 庫混淆。

此外,該庫還可以將 JSON、XML、HTTP Headers、Cookies、逗號分隔列表或文本等相互轉換。

在本教程中,我們將查看以下類:

  1. JSONObject – 類似於 Java 的原生 Map 類型的對象,用於存儲無序的鍵值對
  2. JSONArray – 值的有序序列,類似於 Java 的原生 Vector 實現
  3. JSONTokener – 一種工具,用於將文本分解成一系列 tokens,這些 tokens 可供 JSONObjectJSONArray 使用以解析 JSON 字符串
  4. CDL – 一種工具,提供方法將逗號分隔的文本轉換為 JSONArray,反之亦然
  5. Cookie – 將 JSON String 轉換為 cookies,反之亦然
  6. HTTP – 用於將 JSON String 轉換為 HTTP headers,反之亦然
  7. JSONException – 此庫拋出的標準異常

4. JSONObject

JSONObject 是一種無序的鍵值對集合,類似於 Java 的原生 Map 實現。

  • 鍵是唯一的 String,不能為 null
  • 值可以是布爾值、數字、字符串或 JSONArray 甚至 JSONObject.NULL 對象。
  • JSONObject 可以用包含鍵和值,鍵值之間用冒號分隔,鍵值對之間用逗號分隔的字符串來表示。
  • 它具有多個構造函數,用於創建 JSONObject

它還支持以下主要方法:

  1. get(String key) – 獲取與提供的鍵關聯的對象,如果鍵不存在則拋出 JSONException
  2. opt(String key) – 獲取與提供的鍵關聯的對象,如果鍵不存在則返回 null
  3. put(String key, Object value) – 在當前 JSONObject 中插入或替換鍵值對

put() 方法是一個重載方法,接受 String 類型鍵和多種類型的值。

要查看 JSONObject 支持的完整方法列表,請訪問官方文檔:http://stleary.github.io/JSON-java/org/json/JSONObject.html

現在,讓我們討論一下此類的主要操作。

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() 方法提供了七種不同的重載簽名。雖然鍵只能是唯一的、非空 String,但值可以是任何內容。

4.2. 從 Map 創建 JSON

與其直接將鍵值對放入 JSONObject 中,我們可以構建一個自定義的 Map,然後將其作為參數傳遞給 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 字符串並將其轉換為 JSONObject,只需將 String 傳遞給構造函數。請務必轉義 JSON 字符串中的雙引號。

以下示例將產生與上述相同的結果:

JSONObject jo = new JSONObject(
  "{\"city\":\"chicago\",\"name\":\"jon doe\",\"age\":\"22\"}"
);

傳遞的 String 參數必須是一個有效的 JSON;否則,構造函數可能會拋出 JSONException

4.4. 從 JSON 字符串解析 JSON 值

一旦我們從一個 JSONObject實例中構造出 String,就可以使用相應的 get方法來獲取每個屬性的值。

此外,我們可以為嵌套屬性創建 JSONObject,該屬性的值為 JSON。 我們可以重複執行此操作,以獲取嵌套的 JSON 值,只要需要。 讓我們通過一個示例進行演示:

@Test
void givenJSON_whenParsed_thenCorrectValueReturned() {
    String jsonString = """
                        {
                            "type": "Feature", 
                            "geometry": "Point",
                            "properties": {
                                              "isValid": true, 
                                              "name": "Sample Point"
                                          }
                        }
                        """;
    JSONObject jsonObject = new JSONObject(jsonString);
    String type = jsonObject.getString("type");
    String geometry = jsonObject.getString("geometry");
    JSONObject properties = jsonObject.getJSONObject("properties");
    boolean isValid = properties.getBoolean("isValid");
    assertEquals(type,"Feature");
    assertEquals(geometry,"Point");
    assertTrue(isValid);
}

4.5. 將 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 字符串的方法,但此庫中沒有提供將 JSON 字符串反序列化為 Java 對象的方法。如果需要這種靈活性,我們可以切換到其他庫,例如 Jackson。

5. JSONArray

JSONArray 是一種有序的值集合,類似於 Java 的原生 Vector 實現:

  • 值可以是 NumberStringBooleanJSONArrayJSONObject,甚至可以是 JSONObject.NULL 對象
  • 它以一個用方括號括起來的 String 表示,包含用逗號分隔的值集合
  • 類似於 JSONObject,它具有一個接受源 String 並將其解析為 JSONArray 的構造函數

以下是 JSONArray 類的主要方法:

  1. get(int index) – 返回指定索引(介於 0 和總長度 - 1 之間)的值,否則拋出 JSONException
  2. opt(int index) – 返回與索引(介於 0 和總長度 - 1 之間)關聯的值。如果該索引處沒有值,則返回 null
  3. put(Object value) – 將對象值追加到此 JSONArray 中。此方法是多餘的,並支持各種數據類型

要查看支持 JSONArray 的方法完整列表,請訪問官方文檔:http://stleary.github.io/JSON-java/org/json/JSONArray.html

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"]

5.4. 從 JSONArray 中移除特定元素

我們可以使用實例方法 remove(int index) 移除特定元素。 讓我們繼續使用名為 ja 的 JSONArray(代表州)並使用 remove(int index) 方法移除“阿拉斯加”元素:

ja.remove(3);

之後,我們列出剩餘的 JSONArray:

System.out.println(ja.toString());

確實,它並未列出已刪除的元素:

["California","Texas","Hawaii"]

進一步,我們還可以從 remove(int index) 方法調用本身中找到被移除的元素,因為該方法返回被移除的元素:

Object removed=ja.remove(3);
System.out.println(removed);

確實,它列出了被移除的元素:

Alaska

進一步而言,<em>JSONArray</em> 通過移除一個元素,將其大小減少 1。 值得注意的是,<em>JSONArray</em> 中的索引位置是基於零的。 因此,第一個元素位於索引 0。 相應地,如果我們嘗試使用方法調用 <em>ja.remove(4)</em> 移除同一個元素(假設第 4 個元素位於索引 4),該元素不會被移除。 但是,使用非存在的索引位置的調用不會拋出異常/錯誤。 因此,我們應該驗證元素的移除,就像我們所做的那樣。

6. JSONTokener

一個 <em><strong>JSONTokener</strong></em> 接受一個源 <em><strong>String</strong></em> 作為構造函數的輸入,並從中提取字符和標記。它被用於本包中的類(如 <em><strong>JSONObject</strong></em>、`JSONArray)內部解析 JSON String

可能不會有太多直接使用此類的場景,因為我們可以使用其他更簡單的方法(如 `string.toCharArray())來實現相同的功能。

JSONTokener jt = new JSONTokener("lorem");

while(jt.more()) {
    Log.info(jt.next());
}

現在我們可以像迭代器一樣訪問一個 JSONTokener,使用 more() 方法來檢查是否有剩餘元素,以及 next() 方法來訪問下一個元素。

以下是來自先前示例接收到的令牌:

l
o
r
e
m

7. <em 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);

字符串 cdt 現在包含以下內容:

England,USA,Canada

7.3. 使用逗號分隔文本生成包含 JSONObjectJSONArray

要生成包含 JSONObjectJSONArray,我們將使用包含標題和數據,兩者之間用逗號分隔的文本 String

我們使用回車符 (\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 result 現在包含以下內容(為了清晰起見,格式化輸出如下):

[
    {
        "name": "john",
        "city": "chicago",
        "age": "22"
    },
    {
        "name": "gary",
        "city": "florida",
        "age": "35"
    },
    {
        "name": "sal",
        "city": "vegas",
        "age": "18"
    }
]

請注意,數據和標題都包含在同一個 String 中。我們提供了一種替代方案,通過提供一個 JSONArray 來獲取標題,以及使用逗號分隔的 String 作為數據,從而實現相同的功能。

再次強調,我們使用換行符 (\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);

在這裏,我們將獲取對象 result} 的內容,與之前完全相同。

8. Cookie

Cookie 類處理 Web 瀏覽器 Cookie,並提供將瀏覽器 Cookie 轉換為 JSONObject 以及反之的方法。

以下是 Cookie 類中的主要方法:

  1. toJsonObject(String sourceCookie) – 將 Cookie 字符串轉換為 JSONObject
  2. toString(JSONObject jo) – 前述方法的反向操作,將 JSONObject 轉換為 Cookie String

8.1. 將 Cookie 字符串轉換為 JSONObject

要將 Cookie 字符串轉換為 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 cookie = Cookie.toString(cookieJO);

9. HTTP

HTTP 類包含靜態方法,用於將 HTTP 頭部轉換為 JSONObject,反之亦然。

該類還具有兩個主要方法:

  1. toJsonObject(String sourceHttpHeader) –HttpHeader String 轉換為 JSONObject
  2. toString(JSONObject jo) – 將提供的 JSONObject 轉換為 String

9.1. 將 JSONObject 轉換為 HTTP Header

我們使用 HTTP.toString() 方法將 JSONObject 轉換為 HTTP Header 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 Header 字符串 轉換為 JSONObject

在這裏,我們將我們在上一步驟中獲得的 HTTP 字符串轉換為我們上一步驟中創建的 JSONObject

JSONObject obj = HTTP.toJSONObject("POST \"http://www.example.com/\" HTTP/1.1");

10. JSONException

根據上述,基於包式的應用程序在遇到任何錯誤時會拋出 JSONException 標準異常。

org.json 包中使用了該類,並覆蓋在所有其他類中。當應用程序拋出此異常時,它還包含一條消息,説明具體發生了什麼錯誤。

11. 解析 JSON 布爾值

<i>org.json.JSONObject</i> 可能是 Java 中解析 JSON boolean值的最常用類。讓我們探討解析不同表示形式的 boolean值的各種方法。

11.1. 解析 truefalse

首先,我們從 JSON 字符串中創建一個 JSONObject。然後,我們使用 getBoolean(String)方法獲取 boolean 屬性的值:

@Test
void givenJSONString_whenParsed_thenCorrectBooleanValueReturned() {
    String json = """
                  { 
                      "name": "lorem ipsum",
                      "active": true,
                      "id": 1
                  }
                  """;
    JSONObject jsonObject = new JSONObject(jsonString);
    boolean active = jsonObject.getBoolean("active");
    assertTrue(active);
}

11.2. 解析 0 和 1

通常,我們將 JSON 的 布爾值 表示為 truefalse。 但是,某些系統可能會使用 01 來表示一個 布爾值

我們可以獲取整數值並使用 AssertJ 斷言 assertThat() 來驗證其值為 1

@Test
void givenJSONWithBooleanAs0Or1_whenParsed_correctBooleanValueReturned() {
    String json = """
                  { 
                      "name": "lorem ipsum",
                      "active": 1,
                      "id": 1
                  }
                  """;
    JSONObject jsonObject = new JSONObject(json);
    assertThat(jsonObject.getInt("active")).isEqualTo(1);
}

11.3. 解析 JSON 布爾值混合表示

有時,我們知道一個 JSON 屬性包含一個 布爾值;但是,我們不知道它是否以 true/false0/1 的形式表示。 同樣,我們可以從 JSON 字符串中創建 JSONObject,並進一步從 boolean 屬性中創建 Object

之後,這非常簡單。 如果由此創建的 ObjectInteger 的實例,則我們使用數值表示。 或者,如果 ObjectBoolean 的實例,則我們使用布爾值。

我們可以通過將其轉換為適當的類型來從 Object 中獲取 boolean 值:

@Test
void givenJSONWithMixedRepresentationForBoolean_whenParsed_thenCorrectBooleanValueReturned() {
    JSONObject jsonObject = new JSONObject(json);
    Object activeObject = jsonObject.get("active");
    if (activeObject instanceof Integer value) {
        assertTrue(value == 1);
    } else if (activeObject instanceof Boolean value) {
        assertTrue(value);
      }  
}

12. 結論

在本文中,我們探討了使用 Java 庫 org.json 的方法,並重點介紹了該庫中的一些核心功能。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.