首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Gson 解析 JSON 所有欄位為 null/0:欄位命名、修飾符與註解完整排查清單

     編輯:程式設計綜合問答

現象

ResponseGetUserByUserId 物件經 new Gson().fromJson(json, Clazz.class) 反序列化後,int 全為 0,String 全為 null,但 jsonData 列印正確。

核心排查清單 (按可能性排序)

  1. 欄位為 private 且無 Getter/Setter:Gson 預設**不需要** Getter/Setter,但欄位**必須可見** (非 private 或有 @SerializedName)。
    → 解決:加上 @SerializedName("json_field_name") 或改為 public / package-private。
  2. JSON 鍵名與 Java 欄位名不匹配:如 JSON user_name vs Java userName。
    → 解決:@SerializedName("user_name") 或設定 GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)。
  3. 資料類別為內部類且非 static:非靜態內部類持有外部實例引用,Gson 無法實例化。
    → 解決:改為 static class 或移至頂層類別。
  4. 型別不相容:JSON 數字對應 String 欄位、JSON 陣列對應單一物件。
    → 解決:修正 Java 欄位型別或編寫自訂 TypeAdapter。
  5. Gson 版本過舊:2.2.4 以前對 LocalDateTime、Optional 支援不全。
    → 解決:升級至 2.10+。

最佳實踐範本

public class ResponseGetUserByUserId {
    @SerializedName("user_name")
    private String userName;

    @SerializedName("phone_country_code")
    private int phoneCountryCode;

    // 必須提供無參建構子 (Gson 透過 UnsafeAllocator 實例化,但建議保留)
    public ResponseGetUserByUserId() {}

    // Getter/Setter 可選,但建議提供供業務邏輯使用
    public String getUserName() { return userName; }
    public int getPhoneCountryCode() { return phoneCountryCode; }
}

// 解析
Gson gson = new GsonBuilder()
    .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) // 全域下劃線轉駝峰
    .create();
ResponseGetUserByUserId resp = gson.fromJson(jsonData, ResponseGetUserByUserId.class);

除錯技巧

// 1. 先解析為 JsonObject 檢查結構
JsonObject obj = JsonParser.parseString(jsonData).getAsJsonObject();
System.out.println(obj); // 確認鍵名、巢狀結構

// 2. 開啟 Gson 詳細日誌 (需自行實現 TypeAdapterFactory 記錄)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved