GSON中如何将多个字段解析为一个子对象?

How to parse multiple fields into one sub-object in GSON?

我正在尝试解析一些如下所示的 json 数据:

{
  "store_name": "Coffee Co",
  "location": "New York",
  "supplier_name": "Cups Corps",
  "supplier_id": 12312521,
  "supplier_email": "cups@cups.net"
}

这是我的 Java POJO

class Store {
    @com.google.gson.annotations.SerializedName("store_name")
    String storeName;
    String location;
    Supplier supplier;
}

class Supplier {
    String id;
    String name;
    String email;
}

//Getters and setters omitted

我遇到的问题是 Supplier 的字段被直接扁平化到 Store 记录中。我尝试为 Supplier 添加 TypeAdapter 到我的 Gson 对象,但它没有被触发,因为在传入的 json 对象上没有名为 supplier 的字段。我也不能为 supplier 使用备用名称,因为它需要来自所有三个字段的信息才能创建。

解析此数据以便嵌套的 Supplier 字段也可以填充的最佳方法是什么?

您可以使用自定义解串器:

class StoreDeserializer implements JsonDeserializer<Store> {

    @Override
    public Store deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
        JsonObject jsonObject = jsonElement.getAsJsonObject();

        Supplier supplier = new Supplier(
                jsonObject.get("supplier_id").getAsInt(),
                jsonObject.get("supplier_name").getAsString(),
                jsonObject.get("supplier_email").getAsString()
        );

        return new Store(
                jsonObject.get("store_name").getAsString(),
                jsonObject.get("location").getAsString(),
                supplier
        );
    }
}

然后您可以通过注册反序列化器来反序列化:

String json = "{\"store_name\":\"Coffee Co\",\"location\":\"New York\",\"supplier_name\":\"Cups Corps\",\"supplier_id\":12312521,\"supplier_email\":\"cups@cups.net\"}";
Gson gson = new GsonBuilder().registerTypeAdapter(Store.class, new StoreDeserializer()).create();
Store store = gson.fromJson(json, Store.class);

请注意,我将 Supplier#id 的类型更改为 int,因为它在您的 JSON:

中是数字
class Supplier {
    int id;
    String name, email;

    Supplier(int id, String name, String email) {
        this.id = id;
        this.name = name;
        this.email = email;
    }
}
class Store {
    String storeName, location;
    Supplier supplier;

    Store(String storeName, String location, Supplier supplier) {
        this.storeName = storeName;
        this.location = location;
        this.supplier = supplier;
    }
}