知識庫 / JSON RSS 訂閱

Jsoniter 入門指南

JSON
HongKong
6
09:53 PM · Dec 05 ,2025

1. 簡介

JavaScript 對象表示法(JSON)近年來作為一種數據交換格式越來越受歡迎。 Jsoniter 是一個旨在提供比其他可用的解析器更靈活、更高效的 JSON 解析庫的新型 JSON 解析庫。

在本教程中,我們將學習如何使用 Jsoniter 庫解析 Java 中的 JSON 對象。

2. 依賴項

最新版本的 Jsoniter 可從 Maven 中央倉庫獲取。

讓我們首先在 pom.xml 中添加依賴項:

<dependency>
    <groupId>com.jsoniter<groupId> 
    <artifactId>jsoniter</artifactId>
    <version>0.9.23</version>
</dependency>

同樣,我們也可以將依賴項添加到我們的 build.gradle文件中:

compile group: 'com.jsoniter', name: 'jsoniter', version: '0.9.23'

3. 使用 Jsoniter 解析 JSON

Jsoniter 提供了 3 種 API 用於解析 JSON 文檔:

  • Bind API
  • Any API
  • Iterator API

讓我們分別深入瞭解這些 API。

3.1. 使用 Bind API 解析 JSON 文檔

Bind API 使用傳統的將 JSON 文檔綁定到 Java 類的方式。

請考慮以下包含學生信息的 JSON 文檔:

{"id":1,"name":{"firstName":"Joe","surname":"Blogg"}}

現在,讓我們定義 StudentName 模式類來表示上述 JSON:

public class Student {
    private int id;
    private Name name;
    
    // standard setters and getters
}
public class Name {
    private String firstName;
    private String surname;
    
    // standard setters and getters
}

使用 bind API 將 JSON 解序列化為 Java 對象非常簡單。我們使用 JsonIteratordeserialize 方法:

@Test
public void whenParsedUsingBindAPI_thenConvertedToJavaObjectCorrectly() {
    String input = "{\"id\":1,\"name\":{\"firstName\":\"Joe\",\"surname\":\"Blogg\"}}";
    
    Student student = JsonIterator.deserialize(input, Student.class);

    assertThat(student.getId()).isEqualTo(1);
    assertThat(student.getName().getFirstName()).isEqualTo("Joe");
    assertThat(student.getName().getSurname()).isEqualTo("Blogg");
}

Student模式類聲明id的數據類型為int。 但是,如果接收到的JSON包含id的值為String而不是數字的情況呢? 例如:

{"id":"1","name":{"firstName":"Joe","surname":"Blogg"}}

請注意,JSON 中的 id 是一個字符串值 “1”。Jsoniter 提供 Maybe 解碼器來處理這種情況。

3.2. Maybe 解碼器

Jsoniter 的 Maybe 解碼器在 JSON 元素的數據類型不明確時非常有用student.id 字段的數據類型不明確,它可以是 Stringint。 為了處理這種情況,我們需要使用 MaybeStringIntDecoder 註解我們的 schema 類中的 id 字段:

public class Student {
    @JsonProperty(decoder = MaybeStringIntDecoder.class)
    private int id;
    private Name name;
    
    // standard setters and getters
}

我們現在可以解析 JSON,即使 的值是

@Test
public void givenTypeInJsonFuzzy_whenFieldIsMaybeDecoded_thenFieldParsedCorrectly() {
    String input = "{\"id\":\"1\",\"name\":{\"firstName\":\"Joe\",\"surname\":\"Blogg\"}}";
    
    Student student = JsonIterator.deserialize(input, Student.class);

    assertThat(student.getId()).isEqualTo(1); 
}

同樣,Jsoniter 還提供了其他解碼器,例如 MaybeStringLongDecoderMaybeEmptyArrayDecoder

假設我們期望接收包含 Student 詳情的 JSON 文檔,但實際上我們接收到了以下文檔:

{"error":404,"description":"Student record not found"}

這裏發生了什麼?我們期望收到包含 Student 數據成功的響應,但實際上我們收到了一個 錯誤 響應。 這種情況非常常見,但我們該如何處理呢?

一種方法是進行 null 檢查,以確定我們是否收到了錯誤響應後再提取 Student 數據。 但是,null 檢查可能會導致難以閲讀的代碼,如果我們的 JSON 結構嵌套多層,問題會更加嚴重。

Jsoniter 使用 Any API 進行解析,可以解決這個問題。

3.3. 使用 Any API 解析 JSON

當 JSON 結構本身是動態的,我們可以使用 Jsoniter 的 Any API,它提供無模式的 JSON 解析。 這與將 JSON 解析為 Map<String, Object> 類似。

讓我們再次解析 Student JSON,但這次使用 Any API:

@Test
public void whenParsedUsingAnyAPI_thenFieldValueCanBeExtractedUsingTheFieldName() {
    String input = "{\"id\":1,\"name\":{\"firstName\":\"Joe\",\"surname\":\"Blogg\"}}";
    
    Any any = JsonIterator.deserialize(input);

    assertThat(any.toInt("id")).isEqualTo(1);
    assertThat(any.toString("name", "firstName")).isEqualTo("Joe");
    assertThat(any.toString("name", "surname")).isEqualTo("Blogg"); 
}

讓我們來理解這個例子。首先,我們使用 JsonIterator.deserialize(..) 方法解析 JSON。但是,在此示例中,我們沒有指定任何 schema 類。結果類型為 Any。

接下來,我們使用字段名稱讀取字段值。我們使用 Any.toInt 方法讀取“id”字段值。 Any.toInt 方法將“id”值轉換為整數。 類似地,我們使用 toString 方法讀取“name.firstName”和“name.surname”字段值,並將它們作為字符串值讀取。

使用 Any API,我們還可以檢查 JSON 中是否存在元素。我們可以通過查找元素並檢查查找結果的 valueType 來實現此目的。當元素不存在於 JSON 中時,valueType 將為 INVALID

例如:

@Test
public void whenParsedUsingAnyAPI_thenFieldValueTypeIsCorrect() {
    String input = "{\"id\":1,\"name\":{\"firstName\":\"Joe\",\"surname\":\"Blogg\"}}";
    
    Any any = JsonIterator.deserialize(input);

    assertThat(any.get("id").valueType()).isEqualTo(ValueType.NUMBER);
    assertThat(any.get("name").valueType()).isEqualTo(ValueType.OBJECT);
    assertThat(any.get("error").valueType()).isEqualTo(ValueType.INVALID);
}

“id”和“name”字段在JSON中存在,因此它們的分別是NUMBER和OBJECT。但是,JSON輸入中沒有名為“error”的元素,因此INVALID。

回到上一部分所述的場景,我們需要檢測我們接收到的JSON輸入是否為成功響應或錯誤響應。我們可以通過檢查“error”元素的來判斷是否接收到了錯誤響應:

String input = "{\"error\":404,\"description\":\"Student record not found\"}";
Any response = JsonIterator.deserialize(input);

if (response.get("error").valueType() != ValueType.INVALID) {
    return "Error!! Error code is " + response.toInt("error");
}
return "Success!! Student id is " + response.toInt("id");

運行上述代碼將返回

接下來,我們將探討如何使用迭代器 API 解析 JSON 文檔。

3.4. 使用迭代器 API 解析 JSON

如果我們希望手動進行綁定,可以使用 Jsoniter 的 Iterator API。 讓我們考慮以下 JSON:

{"firstName":"Joe","surname":"Blogg"}

我們將會使用 Name 模式類,該類我們在之前使用過,通過 Iterator API 解析 JSON 數據:

@Test
public void whenParsedUsingIteratorAPI_thenFieldValuesExtractedCorrectly() throws Exception {
    Name name = new Name();    
    String input = "{\"firstName\":\"Joe\",\"surname\":\"Blogg\"}";
    JsonIterator iterator = JsonIterator.parse(input);

    for (String field = iterator.readObject(); field != null; field = iterator.readObject()) {
        switch (field) {
            case "firstName":
                if (iterator.whatIsNext() == ValueType.STRING) {
                    name.setFirstName(iterator.readString());
                }
                continue;
            case "surname":
                if (iterator.whatIsNext() == ValueType.STRING) {
                    name.setSurname(iterator.readString());
                }
                continue;
            default:
                iterator.skip();
        }
    }

    assertThat(name.getFirstName()).isEqualTo("Joe");
    assertThat(name.getSurname()).isEqualTo("Blogg");
}

讓我們理解上面的示例。首先,我們解析 JSON 文檔為一個迭代器。我們使用生成的 JsonIterator 實例來迭代 JSON 元素:

  1. 我們首先調用 readObject 方法,它返回下一個字段名稱(如果文檔末尾已到達,則返回 null)。
  2. 如果字段名稱不感興趣,我們使用 skip 方法跳過 JSON 元素。否則,我們使用 whatIsNext 方法檢查元素的類型。調用 whatIsNext 方法並非必需,但當字段的數據類型未知時非常有用。
  3. 最後,我們使用 readString 方法提取 JSON 元素的的值。

4. 結論

在本文中,我們探討了 Jsoniter 為將 JSON 文檔解析為 Java 對象所提供的各種方法。

首先,我們研究了使用模式類標準方式解析 JSON 文檔的方法。

接下來,我們研究了在解析 JSON 文檔時處理模糊數據類型和動態結構,分別使用 Maybe 解碼器和 Any 數據類型。

最後,我們研究了 Iterator API 用於手動將 JSON 綁定到 Java 對象。

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

發佈 評論

Some HTML is okay.