Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/182.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android Gson-相同字段名,不同类型_Android_Json_Gson - Fatal编程技术网

Android Gson-相同字段名,不同类型

Android Gson-相同字段名,不同类型,android,json,gson,Android,Json,Gson,我今天在另一个问题中问了这个问题,但我担心这不会得到任何解决,因为它是如何措辞的 我有一个json输入,其中包含以下数据: 如您所见,选项_值项是一个对象中的数组,另一个对象中的简单字符串 我怎样才能让Gson正确处理这个问题?我的类将其描述为一个列表对象,因此它适用于option_value是数组的前几个项目,但当它变成字符串时,应用程序崩溃,我得到一个json解析异常 有解决办法吗 更新 根据要求添加我的课程的相关部分: public class Options {

我今天在另一个问题中问了这个问题,但我担心这不会得到任何解决,因为它是如何措辞的

我有一个json输入,其中包含以下数据:

如您所见,选项_值项是一个对象中的数组,另一个对象中的简单字符串

我怎样才能让Gson正确处理这个问题?我的类将其描述为一个列表对象,因此它适用于option_value是数组的前几个项目,但当它变成字符串时,应用程序崩溃,我得到一个json解析异常

有解决办法吗

更新

根据要求添加我的课程的相关部分:

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
        }
    }
公共类选项
{
字符串产品\u选项\u id;
字符串选项\u id;
字符串名;
字符串类型;
所需字符串;
列出选项_值;
//在这里准备好东西
公共类期权价值
{
字符串产品\选项\值\ id;
字符串选项\u值\u id;
字符串名;
字符串图像;
串价;
字符串价格前缀;
//在这里准备好东西
}
}

我为您提供了一个解决方案:)为此,我们应该使用自定义反序列化程序。像这样重新制作您的课程:

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 ;
    }
}
}
@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 ;
}
现在-只要打电话:

Options options = gson.fromJson(json, Options.class);

在我的情况下,同名字段是“data”:{}或“data”:[array_with_real_data]。因此,接受答案中的代码需要稍微修改,如下所示:

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 ;
    }
}
}
@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 ;
}
@覆盖
公共MyClass反序列化(JsonElement json,类型typeOfT,JsonDeserializationContext)
抛出JsonParseException{
MyClass bean=new Gson().fromJson(json,MyClass.class);
JsonObject JsonObject=json.getAsJsonObject();
if(jsonObject.has(“数据”)){
JsonArray数组=jsonObject.getAsJsonArray(“数据”);
if(array!=null&&!array.isJsonNull()){
List data=new Gson().fromJson(数组,new TypeToken(){}.getType());
bean.realData=数据;
}
}
返回豆;
}

希望对您有所帮助。

Hi Asim,您能展示一下您的Json解析器吗?添加了相关部分。我使用的是Gson,因此解析是由该库使用Gson.fromJson(string,class)函数完成的。使用
Gson无法实现这一点。fromJson(string json,class ClassSoft)
,您必须定义适配器。。。让我们通过扩展
com.google.gson.TypeAdapter
类来说
StrangeJsonAdapter
。。。然后使用
StrangeJsonAdapter.fromJson(String json)
方法对json进行解码。在我开始解析这部分json(选项值)之前,它工作得很好。是什么让你认为上面的json不能用fromJson解析?请将Denis answer标记为answer:)我得到了一个StackOverflower错误,这是由于在
Options=new Gson().fromJson(json,Options.class)上的递归反序列化调用引起的和两个新的
Gson
实例是在单个对象的反序列化中创建的。当心。@EpicPandaForce有没有办法防止堆栈溢出?@tamtom我不确定。已经3.5年了,我不记得这个问题,也不记得我的评论。我不记得我到底在什么时候遇到了什么。