GSON 序列化多个属性到子对象
GSON serialize multiple properties to sub object
我一直在我的项目中尝试使用 Retrofit 和 GSON,遇到了一个不寻常的情况,我试图在 Android 上使用 GSON 将两个属性从 JSON 转换为子对象.
示例JSON:
{
"cat1_id": "1111",
"cat1_name": "First Category",
"cat2_id": "2222",
"cat2_name": "Second Category",
}
按照典型的例子,似乎通常会创建一个这样的class。
public class InventoryItem {
private int cat1_id;
private String cat1_name;
private int cat2_id;
private String cat2_id;
}
但是,我宁愿做这样的事情。
public class InventoryItem {
private Category category1;
private Category category2;
}
public class Category {
private int id;
private String name;
}
有没有办法用 GSON 来完成这个?我一直在考虑只创建一个 Retrofit 可以用作响应的 POJO,然后使用 for 循环将其转换为我更喜欢的格式。但这似乎违背了 GSON 的全部目的。
我建议两种方法。
让class充当搭桥人
只需重新定义您的初始 InventoryItem
class,使其充当 InventoryItemBuilder
.
的生成器
class InventoryItemBuilder {
@SerializedName("cat1_id") private int catOneId;
@SerializedName("cat1_name") private String catOneName;
@SerializedName("cat2_id") private int catTwoId;
@SerializedName("cat2_name") private String catTwoName;
public InventoryItem buildInventoryItem() {
Category c1 = new Category(catOneId, catOneName);
Category c2 = new Category(catTwoId, catTwoName);
return new InventoryItem(c1, c2);
}
}
那么在将 JSON 反序列化为 ItemHolder
实例后,您只需调用 buildInventoryItem()
方法即可:
//InventoryItem{category1=Category{id=1111, name='First Category'}, category2=Category{id=2222, name='Second Category'}}
InventoryItem inventoryItem = new Gson().fromJson(json, InventoryItemBuilder.class).buildInventoryItem();
实现自定义解串器
只需告诉解析器您想如何反序列化您描述的 JSON 实体:
class InventoryItemDeserializer implements JsonDeserializer<InventoryItem> {
@Override
public InventoryItem deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject jObject = json.getAsJsonObject();
Category c1 = new Category(jObject.get("cat1_id").getAsInt(), jObject.get("cat1_name").getAsString());
Category c2 = new Category(jObject.get("cat2_id").getAsInt(), jObject.get("cat2_name").getAsString());
return new InventoryItem(c1, c2);
}
}
然后在解析器中注册:
Gson gson = new GsonBuilder().registerTypeAdapter(InventoryItem.class, new InventoryItemDeserializer()).create();
并使用它:
InventoryItem inventoryItem = gson.fromJson(json, InventoryItem.class);
这会产生与以前相同的输出。当然,反序列化器可能不太具体(例如,通过遍历对象的条目集)。这应该会给你一些见解。
希望对您有所帮助! :)
为了将来参考,这里是我正在测试的解决方案示例。
public class InventoryItem {
@SerializedName("AUTO") private int mPersistentId;
@SerializedName("ID") private String mItemId;
@SerializedName("BARCODE") private String mBarcode;
@SerializedName("ALIAS") private String mAlias;
@SerializedName("ALIAS2") private String mAlias2;
@SerializedName("NAME") private String mDescription;
private Category mCategory;
private Category mSubCategory;
private Category mFinalCategory;
}
这是我的自定义解串器
public class InventoryItemDeserializer implements JsonDeserializer<InventoryItem> {
private static final Gson GSON = new GsonBuilder().create();
@Override
public InventoryItem deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject jObject = json.getAsJsonObject();
InventoryItem item = GSON.fromJson(json, InventoryItem.class);
item.setCategory(new Category(jObject.get("cat1_id").getAsInt(), jObject.get("cat1_name").getAsString()));
item.setSubCategory(new Category(jObject.get("cat2_id").getAsInt(), jObject.get("cat2_name").getAsString()));
item.setFinalCategory(new Category(jObject.get("cat3_id").getAsInt(), jObject.get("cat3_name").getAsString()));
return item;
}
}
我一直在我的项目中尝试使用 Retrofit 和 GSON,遇到了一个不寻常的情况,我试图在 Android 上使用 GSON 将两个属性从 JSON 转换为子对象.
示例JSON:
{
"cat1_id": "1111",
"cat1_name": "First Category",
"cat2_id": "2222",
"cat2_name": "Second Category",
}
按照典型的例子,似乎通常会创建一个这样的class。
public class InventoryItem {
private int cat1_id;
private String cat1_name;
private int cat2_id;
private String cat2_id;
}
但是,我宁愿做这样的事情。
public class InventoryItem {
private Category category1;
private Category category2;
}
public class Category {
private int id;
private String name;
}
有没有办法用 GSON 来完成这个?我一直在考虑只创建一个 Retrofit 可以用作响应的 POJO,然后使用 for 循环将其转换为我更喜欢的格式。但这似乎违背了 GSON 的全部目的。
我建议两种方法。
让class充当搭桥人
只需重新定义您的初始 InventoryItem
class,使其充当 InventoryItemBuilder
.
class InventoryItemBuilder {
@SerializedName("cat1_id") private int catOneId;
@SerializedName("cat1_name") private String catOneName;
@SerializedName("cat2_id") private int catTwoId;
@SerializedName("cat2_name") private String catTwoName;
public InventoryItem buildInventoryItem() {
Category c1 = new Category(catOneId, catOneName);
Category c2 = new Category(catTwoId, catTwoName);
return new InventoryItem(c1, c2);
}
}
那么在将 JSON 反序列化为 ItemHolder
实例后,您只需调用 buildInventoryItem()
方法即可:
//InventoryItem{category1=Category{id=1111, name='First Category'}, category2=Category{id=2222, name='Second Category'}}
InventoryItem inventoryItem = new Gson().fromJson(json, InventoryItemBuilder.class).buildInventoryItem();
实现自定义解串器
只需告诉解析器您想如何反序列化您描述的 JSON 实体:
class InventoryItemDeserializer implements JsonDeserializer<InventoryItem> {
@Override
public InventoryItem deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject jObject = json.getAsJsonObject();
Category c1 = new Category(jObject.get("cat1_id").getAsInt(), jObject.get("cat1_name").getAsString());
Category c2 = new Category(jObject.get("cat2_id").getAsInt(), jObject.get("cat2_name").getAsString());
return new InventoryItem(c1, c2);
}
}
然后在解析器中注册:
Gson gson = new GsonBuilder().registerTypeAdapter(InventoryItem.class, new InventoryItemDeserializer()).create();
并使用它:
InventoryItem inventoryItem = gson.fromJson(json, InventoryItem.class);
这会产生与以前相同的输出。当然,反序列化器可能不太具体(例如,通过遍历对象的条目集)。这应该会给你一些见解。
希望对您有所帮助! :)
为了将来参考,这里是我正在测试的解决方案示例。
public class InventoryItem {
@SerializedName("AUTO") private int mPersistentId;
@SerializedName("ID") private String mItemId;
@SerializedName("BARCODE") private String mBarcode;
@SerializedName("ALIAS") private String mAlias;
@SerializedName("ALIAS2") private String mAlias2;
@SerializedName("NAME") private String mDescription;
private Category mCategory;
private Category mSubCategory;
private Category mFinalCategory;
}
这是我的自定义解串器
public class InventoryItemDeserializer implements JsonDeserializer<InventoryItem> {
private static final Gson GSON = new GsonBuilder().create();
@Override
public InventoryItem deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject jObject = json.getAsJsonObject();
InventoryItem item = GSON.fromJson(json, InventoryItem.class);
item.setCategory(new Category(jObject.get("cat1_id").getAsInt(), jObject.get("cat1_name").getAsString()));
item.setSubCategory(new Category(jObject.get("cat2_id").getAsInt(), jObject.get("cat2_name").getAsString()));
item.setFinalCategory(new Category(jObject.get("cat3_id").getAsInt(), jObject.get("cat3_name").getAsString()));
return item;
}
}