知識庫 / JSON RSS 訂閱

將 JSONObject 映射到 POJO

JSON
HongKong
15
09:40 PM · Dec 05 ,2025

1. 簡介

在處理 API 或配置文件時,JSON 通常是首選的數據交換格式。在 Java 中,<em >org.json</em> 庫提供了一種簡單的方法來解析和處理 JSON 數據。將 JSON 轉換為 Java POJO 至關重要,因為它使我們能夠使用類型化的對象而不是原始文本或映射,從而提高可讀性、可維護性和驗證能力。

在本教程中,我們將學習如何將 <em >JSONObject</em> 轉換為 Java POJO。我們使用一個簡單的示例來理解該過程,包括轉換 JSON 字符串、處理嵌套對象以及驗證映射結果。

2. 項目設置

在開始之前,讓我們將 org.json 庫包含到項目中,以便方便地解析和處理 JSON 數據:

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

該庫提供 JSONObjectJSONArray 類,使在 Java 中創建、讀取和操作 JSON 變得更加容易。

3. 定義POJO類

接下來,我們定義一個簡單的<em >User</em>類來表示JSON數據的結構。該類作為目標對象,用於將JSON映射到其中:

class User {
    private String name;
    private int age;
    private String email;
    private Address address;

    // Getters and setters
}

class Address {
    private String city;
    private String postalCode;

    // Getters and setters
}

這些類反映了 JSON 數據的結構,因此將 JSON 和 Java 對象之間的轉換變得簡單明瞭。

4. 創建一個示例 JSONObject

現在,我們將創建一個示例字符串並將其轉換為 JSONObject

假設示例 JSON 字符串模擬了一個典型的場景,即應用程序從 API 或配置文件接收 JSON 數據:

String jsonString = """
{
  "name": "Alice",
  "age": 25,
  "email": "[email protected]",
  "address": {
    "city": "Singapore",
    "postalCode": "123456"
  }
}
""";

JSONObject jsonObject = new JSONObject(jsonString);

因此,JSON 包含一個嵌套的 地址 對象,反映了真實的 JSON 結構.

有了 User POJO 和 JSONObject 準備好後,存在多種方法將此 JSON 數據轉換為 Java 對象,無論是手動還是通過像 Jackson 這樣的庫。

5. 手動映射

手動映射涉及從 JSONObject 中提取每個值,並將其設置到 POJO 中對應的字段中。

為此,我們創建一個方法,手動將 JSONObject 映射到 POJO:

public static User mapManually(JSONObject jsonObject) {
    User user = new User();
    user.setName(jsonObject.getString("name"));
    user.setAge(jsonObject.getInt("age"));
    user.setEmail(jsonObject.getString("email"));

    JSONObject addressObject = jsonObject.getJSONObject("address");
    Address address = new Address();
    address.setCity(addressObject.getString("city"));
    address.setPostalCode(addressObject.getString("postalCode"));
    user.setAddress(address);

    return user;
}

這種方法清晰易懂,通常在JSON結構較小且穩定時表現良好。 每個字段都明確映射,從而實現自定義處理,例如默認值或轉換

儘管如此,手動映射確實能保證正確的值,正如測試結果所示:

User user = mapManually(jsonObject);

assertEquals("Alice", user.getName());
assertEquals(25, user.getAge());
assertEquals("[email protected]", user.getEmail());
assertEquals("Singapore", user.getAddress().getCity());
assertEquals("123456", user.getAddress().getPostalCode());

然而,對於大型或深度嵌套的 JSON 結構,手動映射變得重複且容易出錯。

6. 使用 Jackson

Jackson 是一個流行的庫,可以自動將 JSON 字符串映射到 POJO。

6.1. 基本概念

要使用 Jackson,我們需要添加相應的 pom.xml 依賴項:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.16.0</version>
</dependency>

JSONObject 轉換為 JSON 字符串後,Jackson 通過單個方法調用處理映射:

public static User mapWithJackson(JSONObject jsonObject) {
    ObjectMapper mapper = new ObjectMapper();
    try {
        return mapper.readValue(jsonObject.toString(), User.class);
    } catch (Exception e) {
        return null;
    }
}

Jackson 消除了手動映射所需的絕大部分樣板代碼,並自動管理複雜的 JSON 結構。它還會將嵌套對象映射,例如 地址 字段,當 POJO 結構與 JSON 層次結構匹配時。

6.2. 集合 (Collections)

集合,如列表和數組,無需額外設置即可支持。例如,假設 JSON 中包含一個電話號碼數組:

{
  "name": "Alice",
  "age": 25,
  "email": "[email protected]",
  "address": {
    "city": "Singapore",
    "postalCode": "123456"
  },
  "phones": ["12345678", "87654321"]
}

可以在 User 類中添加一個對應的 List<String> 字段:

private List<String> phones;

Jackson 會自動將 phones 數組映射為 Java 的 List。 這對於那些 JSON 數據經常包含嵌套對象和數組的 API 來説非常適用。

6.3. 定製化

此外,Jackson 還通過註解支持定製。例如,如果 JSON 字段名稱與 Java 屬性不同,則 @JsonProperty 註解可以定義映射關係:

class User {
    @JsonProperty("full_name")
    private String name;
    private int age;
    private String email;
    // Getters and setters
}

傑克遜會從JSON中讀取 full_name 字段並自動將其賦值給 name 屬性。 這種靈活性在與使用不同命名規範的API進行集成時非常有用

傑克遜還支持多態反序列化,使其能夠處理表示基本類多個子類型的JSON。例如,考慮一個基本類 Animal 和兩個子類,DogCat

@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "type"
)
@JsonSubTypes({
    @JsonSubTypes.Type(value = Dog.class, name = "dog"),
    @JsonSubTypes.Type(value = Cat.class, name = "cat")
})
abstract class Animal {
    private String name;
    // Getter and setter
}

class Dog extends Animal {
    private int barkVolume;
    // Getter and setter
}

class Cat extends Animal {
    private boolean likesFish;
    // Getter and setter
}

使用這種配置,Jackson 會根據 JSON 中 type 字段自動確定要實例化哪個子類

[
  { "type": "dog", "name": "Buddy", "barkVolume": 5 },
  { "type": "cat", "name": "Mimi", "likesFish": true }
]

可以使用 Jackson 的 ObjectMapper 將 JSON 映射到正確的子類:

ObjectMapper mapper = new ObjectMapper();
List<Animal> animals = Arrays.asList(
    mapper.readValue(jsonArrayString, Animal[].class)
);

傑克遜在第一條記錄中創建了一個 Dog 對象,在第二條記錄中創建了一個 Cat 對象,無需額外的邏輯。

6.4. 驗證

我們可以驗證 Jackson 映射是否正確工作:

User user = mapWithJackson(jsonObject);

assertEquals("Alice", user.getName());
assertEquals("Singapore", user.getAddress().getCity());
assertEquals("123456", user.getAddress().getPostalCode());
assertEquals(2, user.getPhones().size());
assertEquals("12345678", user.getPhones().get(0));
assertEquals("87654321", user.getPhones().get(1));

斷言驗證了映射。

7. 使用 Gson

Gson 是另一個流行的庫,用於將 JSON 映射到 Java 對象。在使用它之前,我們需要在 pom.xml 中添加 Gson 依賴。

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.10.1</version>
</dependency>

Gson 解析 JSON 字符串並填充 POJO 的字段,包括嵌套對象和集合,無需額外配置。

因此,我們可以創建一個簡單的映射方法,將 JSONObject 映射到 User 類。

public static User mapWithGson(JSONObject jsonObject) {
    Gson gson = new Gson();
    return gson.fromJson(jsonObject.toString(), User.class);
}

我們使用斷言來驗證 Gson 映射是否正確:

User user = mapWithGson(jsonObject);

assertEquals("Alice", user.getName());
assertEquals(25, user.getAge());
assertEquals("Singapore", user.getAddress().getCity());
assertEquals(2, user.getPhones().size());

Gson 是一款輕量級且易於使用的庫,適用於快速轉換或小型應用程序。 無需額外配置,它在我們需要簡單的 JSON 到 POJO 映射時非常實用。

8. 結論

在本文中,我們探討了使用手動映射、Jackson 和 Gson 將 JSONObject 轉換為 Java POJO 的幾種方法。手動映射提供完全的控制,適用於簡單的 JSON 結構,而 Jackson 則提供一個功能強大且靈活的選項,具有註解支持和多態處理功能。Gson 則適用於輕量級用例,提供簡潔性。

如往常一樣,源代碼可在 GitHub 上找到:https://github.com/eugenp/tutorials/tree/master/json-modules/json-3

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

發佈 評論

Some HTML is okay.