如何使用 Gson 正确解析嵌套 JSON 结构(避免字段为 null)

gson 反序列化时字段全为 null,通常是因为 java 类结构与 json 层级不匹配。本文详解如何通过创建顶层封装类,精准映射多层嵌套 json,确保 taxes、billto 等子对象被正确反序列化。

在你提供的 JSON 中,billingInformation 并非根对象,而是外层的一个字段名,其值才是真正的 BillingInformation 数据。而你直接将整个 JSON 字符串反序列化为 BillingInformation.class,Gson 会尝试将最外层的 { "billingInformation": { ... } }

强行映射到 BillingInformation 的字段上——但外层根本没有 taxes、billTo 等字段,只有 "billingInformation" 这一个 key,因此所有内部字段均无法匹配,全部返回 null。

✅ 正确做法是:严格遵循 JSON 的层级结构定义 Java 类

你的 JSON 结构为:

{
  "billingInformation": {  // ← 这是根级字段
    "taxes": { ... },
    "billTo": { ... },
    ...
  }
}

因此,你需要一个顶层封装类(例如 Data 或 Root),它包含一个名为 billingInformation 的字段,类型为 BillingInformation:

public class Data {
    @SerializedName("billingInformation")
    private BillingInformation billingInformation;

    // 必须提供无参构造函数(Gson 反序列化必需)
    public Data() {}

    public BillingInformation getBillingInformation() {
        return billingInformation;
    }

    public void setBillingInformation(BillingInformation billingInformation) {
        this.billingInformation = billingInformation;
    }
}

然后修改反序列化代码:

String json = new String(Files.readAllBytes(Paths.get(path)));
Data data = gson.fromJson(json, Data.class);
BillingInformation billingInfo = data.getBillingInformation(); // ✅ 现在不再为 null

⚠️ 同时,请确保你的子类(如 Taxes、BillTo、Items 等)也正确定义,并与 JSON 字段名一致(或通过 @SerializedName 显式标注)。例如:

public class Taxes {
    @SerializedName("gst") private double gst;
    @SerializedName("hst") private double hst;
    // getter/setter...
}

? 补充注意事项:

  • 所有参与 Gson 反序列化的类必须有无参构造函数(默认即满足);
  • 字段名大小写需与 JSON 严格一致,或统一用 @SerializedName 注解声明;
  • 若 items.item 是数组,Items 类中对应字段应为 List 类型,且 Item 类需完整定义 hsnCode、description 等字段;
  • 推荐启用 GsonBuilder.setLenient() 仅用于调试;生产环境应保持严格模式以捕获格式错误。

通过这种“逐层建模”的方式,Gson 才能准确将 JSON 的每一层键值对映射到对应的 Java 对象字段,彻底解决空值问题。