使用 Jackson 映射動態 JSON 對象

Jackson
Remote
1
09:13 PM · Nov 30 ,2025

1. 簡介

使用 Jackson 處理預定義的 JSON 數據結構非常簡單。然而,有時我們需要處理動態的 JSON 對象

在本快速教程中,我們將學習多種將動態 JSON 對象映射到 Java 類的方法。

請注意,在所有測試用例中,我們假設擁有 objectMapper 字段。

2. 使用 JsonNode

假設我們要處理在線商店中的產品規格。所有產品都具有一些共同的屬性,但它們也具有不同的屬性,具體取決於產品的類型。

例如,我們想知道手機顯示屏的寬高比,但這個屬性對於鞋子來説意義不大。

數據結構如下所示:

 {
    "name": "Pear yPhone 72",
    "category": "cellphone",
    "details": {
        "displayAspectRatio": "97:3",
        "audioConnector": "none"
    }
}

我們存儲動態屬性在 details 對象中。

我們可以使用以下 Java 類映射常見的屬性:

 class Product {

    String name;
    String category;

    // standard getters and setters
}

除此之外,我們需要一個合適的 details 對象表示形式。例如,com.fasterxml.jackson.databind.JsonNode 可以處理動態鍵

要使用它,我們需要將其作為字段添加到我們的 Product 類中:

 class Product {

    // common fields

    JsonNode details;

    // standard getters and setters
}

最後,我們驗證它是否有效:

 String json = "<json object>";

Product product = objectMapper.readValue(json, Product.class);

assertThat(product.getName()).isEqualTo("Pear yPhone 72");
assertThat(product.getDetails().get("audioConnector").asText()).isEqualTo("none");

但是,這個解決方案存在問題;我們的類依賴於 Jackson 庫,因為我們有一個 JsonNode 字段。

3. 使用 Map

我們可以通過使用 java.util.Map 來處理 details 字段。更具體地説,我們需要使用 Map<String, Object>.

其他部分可以保持不變:

class Product {

    // common fields

    Map<String, Object> details;

    // standard getters and setters
}

然後我們可以用一個測試來驗證它:

String json = "<json object>";

Product product = objectMapper.readValue(json, Product.class);

assertThat(product.getName()).isEqualTo("Pear yPhone 72");
assertThat(product.getDetails().get("audioConnector")).isEqualTo("none");

4. 使用

之前的解決方案在對象僅包含動態屬性時是好的選擇。但是,有時我們會在單個JSON對象中混合使用

例如,我們需要扁平化我們的產品表示:

 {
    "name": "Pear yPhone 72",
    "category": "cellphone",
    "displayAspectRatio": "97:3",
    "audioConnector": "none"
}

我們可以將這種結構視為動態對象。然而,這意味着我們無法定義常見的屬性,我們必須動態地處理它們。

或者,我們可以使用 來標記一個用於處理附加未知屬性的方法。 這樣的方法應該接受兩個參數,屬性的名稱和值:

 class Product {

    // common fields

    Map<String, Object> details = new LinkedHashMap<>();

    @JsonAnySetter
    void setDetail(String key, Object value) {
        details.put(key, value);
    }

    // standard getters and setters
}

請注意,我們必須實例化 以避免

由於我們存儲動態屬性到 中,我們可以以與之前相同的方式使用它:

 String json = "<json object>";

Product product = objectMapper.readValue(json, Product.class);

assertThat(product.getName()).isEqualTo("Pear yPhone 72");
assertThat(product.getDetails().get("audioConnector")).isEqualTo("none");

5. 創建自定義反序列器

對於大多數情況,這些解決方案都很好用;然而,有時我們需要更多的控制。例如,我們可以將 JSON 對象的反序列化信息存儲在數據庫中。

我們可以使用自定義反序列器來處理這些情況。由於這是一個更復雜的主題,因此我們在另一篇文章中進行了介紹,即“Jackson 中的自定義反序列化入門”。

6. 結論

在本文中,我們討論了多種處理動態 JSON 對象的方法,這些方法使用了 Jackson。

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

發佈 評論

Some HTML is okay.