首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 物件與 JSON 互轉完整指南:Gson 庫實戰與巢狀集合處理

     編輯:Java 相關知識

Google Gson 是 Java 處理 JSON 最主流的庫之一。本文示範:POJO 定義、巢狀 List 結構、toJson() 序列化、fromJson() 反序列化、GsonBuilder 進階配置(日期格式、null 處理、欄位命名策略)。

Maven 依賴

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

POJO 定義(巢狀結構)

import java.util.List;

class JsonOpen {
    private List<Zone> zones;
    public List<Zone> getZones() { return zones; }
    public void setZones(List<Zone> zones) { this.zones = zones; }
}

class Zone {
    private List<CardObject> cards;
    public List<CardObject> getCards() { return cards; }
    public void setCards(List<CardObject> cards) { this.cards = cards; }
}

class CardObject {
    private String zone, line, row, batch, number, path;
    // getter/setter 略(IDE 自動產生)
}

序列化:物件 → JSON

public static void toJson() {
    List<CardObject> cards = new ArrayList<>();
    for (char c = 'A'; c <= 'E'; c++) {
        CardObject co = new CardObject();
        co.setZone("A");
        co.setLine(String.valueOf(c));
        co.setRow("1");
        co.setBatch("15315AA020");
        co.setNumber("008100000803");
        co.setPath("");
        cards.add(co);
    }

    Zone zone = new Zone();
    zone.setCards(cards);

    JsonOpen jo = new JsonOpen();
    jo.setZones(List.of(zone));

    Gson gson = new GsonBuilder().setPrettyPrinting().create();  // 格式化輸出
    String json = gson.toJson(jo);
    System.out.println(json);
}

輸出範例

{
  "zones": [
    {
      "cards": [
        {"zone":"A","line":"A","row":"1","batch":"15315AA020","number":"008100000803","path":""},
        {"zone":"A","line":"B","row":"1","batch":"15315AA020","number":"008100000803","path":""},
        ...
      ]
    }
  ]
}

反序列化:JSON → 物件

public static void fromJson() {
    String json = "{\"zones\":[{\"cards\":[{\"zone\":\"A\",\"line\":\"A\",\"row\":\"1\",\"batch\":\"15315AA020\",\"number\":\"008100000803\",\"path\":\"\"},{\"zone\":\"A\",\"line\":\"B\",\"row\":\"1\",\"batch\":\"15315AA020\",\"number\":\"008100000803\",\"path\":\"\"}]}]}";

    Gson gson = new Gson();
    JsonOpen jo = gson.fromJson(json, JsonOpen.class);

    System.out.println("Zone 數: " + jo.getZones().size());
    for (Zone z : jo.getZones()) {
        for (CardObject c : z.getCards()) {
            System.out.printf("Zone:%s Line:%s Row:%s Batch:%s No:%s%n",
                c.getZone(), c.getLine(), c.getRow(), c.getBatch(), c.getNumber());
        }
    }
}

GsonBuilder 進階配置速查

配置作用
setPrettyPrinting()輸出縮排易讀 JSON
serializeNulls()序列化時保留 null 欄位(預設略過)
setDateFormat("yyyy-MM-dd HH:mm:ss")統一日期格式
setFieldNamingPolicy(LOWER_CASE_WITH_UNDERSCORES)駝峰轉蛇形命名(userName → user_name)
excludeFieldsWithoutExposeAnnotation()僅序列化標註 @Expose 的欄位
registerTypeAdapter()自訂類型序列化/反序列化邏輯

常見坑與解法

  • 泛型擦除導致 List<T> 反序列化失敗:使用 TypeToken:
    Type listType = new TypeToken<List<CardObject>>(){}.getType();
    List<CardObject> list = gson.fromJson(json, listType);
  • 日期格式不一致:統一用 setDateFormat 或自訂 JsonDeserializer。
  • 欄位名不符:加 @SerializedName("json_field") 映射。
  • 循環引用:使用 @Expose 控制或寫自訂 TypeAdapter。

替代庫快速比較

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
庫優點缺點
Gson簡單、效能佳、Google 維護預設略過 null、泛型需 TypeToken
Jackson功能最全、Spring Boot 預設、串流 APIAPI 複雜、體積較大
JSON-B (Jakarta)標準規範、CDI 整合生態較新、實作較少