Gson - 相同的字段名称,不同的类型
Gson - Same field name, different types
我今天在另一个问题中问过这个问题,但由于它的措辞,恐怕无法得到任何解决方案。
我有一个 json 输入,其中包含以下数据:
如您所见,option_value项在一个对象中是一个数组,在另一个对象中是一个简单的字符串。
如何让 Gson 正确处理这个问题?我的 class 将其描述为一个 List 对象,因此它适用于前几个项目,其中 option_value 是一个数组,但是当它变成 string,应用程序崩溃,我得到一个 json 解析异常 .
有解决办法吗?
更新
根据要求添加我的 class 的相关部分:
public class Options
{
String product_option_id;
String option_id;
String name;
String type;
String required;
List<OptionValue> option_value;
// get set stuff here
public class OptionValue
{
String product_option_value_id;
String option_value_id;
String name;
String image;
String price;
String price_prefix;
// get set stuff here
}
}
我有一个解决方案给你 :) 为此,我们应该使用自定义反序列化器。像这样重制你的 class:
public class Options{
@SerializedName ("product_option_id");
String mProductOptionId;
@SerializedName ("option_id");
String mOptionId;
@SerializedName ("name");
String mName;
@SerializedName ("type");
String mType;
@SerializedName ("required");
String mRequired;
//don't assign any serialized name, this field will be parsed manually
List<OptionValue> mOptionValue;
//setter
public void setOptionValues(List<OptionValue> optionValues){
mOptionValue = optionValues;
}
// get set stuff here
public class OptionValue
{
String product_option_value_id;
String option_value_id;
String name;
String image;
String price;
String price_prefix;
// get set stuff here
}
public static class OptionsDeserilizer implements JsonDeserializer<Options> {
@Override
public Offer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
Options options = new Gson().fromJson(json, Options.class);
JsonObject jsonObject = json.getAsJsonObject();
if (jsonObject.has("option_value")) {
JsonElement elem = jsonObject.get("option_value");
if (elem != null && !elem.isJsonNull()) {
String valuesString = elem.getAsString();
if (!TextUtils.isEmpty(valuesString)){
List<OptionValue> values = new Gson().fromJson(valuesString, new TypeToken<ArrayList<OptionValue>>() {}.getType());
options.setOptionValues(values);
}
}
}
return options ;
}
}
}
在让 gson 解析 json 之前,我们应该注册我们的自定义反序列化器:
Gson gson = new GsonBuilder()
.registerTypeAdapter(Options.class, new Options.OptionsDeserilizer())
.create();
现在 - 只需拨打:
Options options = gson.fromJson(json, Options.class);
在我的情况下,同名字段是 "data":{} 或 "data":[array_with_real_data]。因此,接受的答案中的代码需要稍微修改,如下所示:
@Override
public MyClass deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
MyClass bean = new Gson().fromJson(json, MyClass.class);
JsonObject jsonObject = json.getAsJsonObject();
if (jsonObject.has("data")) {
JsonArray array = jsonObject.getAsJsonArray("data");
if (array != null && !array.isJsonNull()) {
List<Data> data = new Gson().fromJson(array, new TypeToken<ArrayList<Data>>() {}.getType());
bean.realData = data;
}
}
return bean ;
}
希望对您有所帮助。
我今天在另一个问题中问过这个问题,但由于它的措辞,恐怕无法得到任何解决方案。
我有一个 json 输入,其中包含以下数据:
如您所见,option_value项在一个对象中是一个数组,在另一个对象中是一个简单的字符串。
如何让 Gson 正确处理这个问题?我的 class 将其描述为一个 List 对象,因此它适用于前几个项目,其中 option_value 是一个数组,但是当它变成 string,应用程序崩溃,我得到一个 json 解析异常 .
有解决办法吗?
更新
根据要求添加我的 class 的相关部分:
public class Options
{
String product_option_id;
String option_id;
String name;
String type;
String required;
List<OptionValue> option_value;
// get set stuff here
public class OptionValue
{
String product_option_value_id;
String option_value_id;
String name;
String image;
String price;
String price_prefix;
// get set stuff here
}
}
我有一个解决方案给你 :) 为此,我们应该使用自定义反序列化器。像这样重制你的 class:
public class Options{
@SerializedName ("product_option_id");
String mProductOptionId;
@SerializedName ("option_id");
String mOptionId;
@SerializedName ("name");
String mName;
@SerializedName ("type");
String mType;
@SerializedName ("required");
String mRequired;
//don't assign any serialized name, this field will be parsed manually
List<OptionValue> mOptionValue;
//setter
public void setOptionValues(List<OptionValue> optionValues){
mOptionValue = optionValues;
}
// get set stuff here
public class OptionValue
{
String product_option_value_id;
String option_value_id;
String name;
String image;
String price;
String price_prefix;
// get set stuff here
}
public static class OptionsDeserilizer implements JsonDeserializer<Options> {
@Override
public Offer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
Options options = new Gson().fromJson(json, Options.class);
JsonObject jsonObject = json.getAsJsonObject();
if (jsonObject.has("option_value")) {
JsonElement elem = jsonObject.get("option_value");
if (elem != null && !elem.isJsonNull()) {
String valuesString = elem.getAsString();
if (!TextUtils.isEmpty(valuesString)){
List<OptionValue> values = new Gson().fromJson(valuesString, new TypeToken<ArrayList<OptionValue>>() {}.getType());
options.setOptionValues(values);
}
}
}
return options ;
}
}
}
在让 gson 解析 json 之前,我们应该注册我们的自定义反序列化器:
Gson gson = new GsonBuilder()
.registerTypeAdapter(Options.class, new Options.OptionsDeserilizer())
.create();
现在 - 只需拨打:
Options options = gson.fromJson(json, Options.class);
在我的情况下,同名字段是 "data":{} 或 "data":[array_with_real_data]。因此,接受的答案中的代码需要稍微修改,如下所示:
@Override
public MyClass deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
MyClass bean = new Gson().fromJson(json, MyClass.class);
JsonObject jsonObject = json.getAsJsonObject();
if (jsonObject.has("data")) {
JsonArray array = jsonObject.getAsJsonArray("data");
if (array != null && !array.isJsonNull()) {
List<Data> data = new Gson().fromJson(array, new TypeToken<ArrayList<Data>>() {}.getType());
bean.realData = data;
}
}
return bean ;
}
希望对您有所帮助。