Java Gson:JsonArray无法转换为JsonPrimitive错误

Java Gson:JsonArray无法转换为JsonPrimitive错误,java,json,gson,Java,Json,Gson,我想使用Gson解析包含动态字段类型的json对象: { "rows": [ { "id": "1", "interventions": [ { "type": "type1", "label": "label 1" }, { "type": "type2",

我想使用Gson解析包含动态字段类型的json对象:

{
"rows":
   [
      {
         "id": "1",
         "interventions": [
            {
               "type": "type1",
               "label": "label 1"
            },
            {
               "type": "type2",
               "label": ["label 1","label 2"]
           },
           {
              "type": "type3",
              "label": "label 3",
           }
        ]
     }
  ]
}

正如您所看到的,“标签”字段可以是字符串或字符串列表

我编写了一个定制的反序列化程序来处理这个问题,如果“干预”字段只有一个元素(不管“标签”字段是字符串还是列表),它都可以工作:

}

但是总是抛出com.google.gson.JsonArray不能被强制转换为com.google.gson.JsonPrimitive异常,如果存在多个“干预”元素

以下是自定义反序列化程序:

public class CustomDeserializer implements JsonDeserializer<InterventionsModel> {

@Override
public InterventionsModel deserialize(JsonElement je, Type type, JsonDeserializationContext jdc) throws JsonParseException {

    if(je != null && je.getAsJsonObject()!=null) {

        JsonPrimitive jp = je.getAsJsonObject().getAsJsonPrimitive("label");
        if (jp != null && jp.isString()) {

            String label = jp.getAsString();            
            List<String> list = new ArrayList<String>(1);
            list.add(label);

            InterventionsModel interventionsModel = new InterventionsModel();
            interventionsModel.setLabel(list);

            return interventionsModel;            
        }
    }

    return new Gson().fromJson(je, InterventionsModel.class);
}
对象的类包括:

public class ResultsModel {
private List<RowModel> rows;

//getter and setter ..    
公共类ResultsModel{
私有列表行;
//接二连三。。
}

公共类行模型{
私有字符串id;
私人名单干预措施;
//接二连三
}

公共类干预模型{
私有字符串类型;
私有列表标签;
//接二连三
}


有人能帮忙吗?

您不必为整个
干预模型创建自定义反序列化程序
相反,只需将
@JsonAdapter
注释应用于
列表标签
字段

public class InterventionsModel {
    private String type;

    @JsonAdapter(LabelsDeserializer.class)
    private List<String> label;

    // Setters and getters
}

看看非常相似的问题:,谢谢你的回答。我修复了类型与干预类型的不匹配。@Karen嗨!我发布的代码是现成的。我已经用你提供的输入测试过了。基本上只是复制粘贴itI按照您的建议注册了新的自定义反序列化程序,如下所示:builder.registerTypeAdapter(List.class,new LabelsDeserializer());但是现在我得到了另一个错误:java.lang.UnsupportedOperationException:JsonObject。@Karen您不必注册任何东西。Gson将自动执行所有操作。只需按我显示的那样放置注释。如果我不注册它,我会得到java.lang.IllegalArgumentException:@JsonAdapter值必须是TypeAdapter或TypeAdapterFactory引用异常。。。
public class ResultsModel {
private List<RowModel> rows;

//getter and setter ..    
public class RowModel {
private String id;    
private List<InterventionsModel> interventions;
//getter and setter
public class InterventionsModel {
private String type;
private List<String> label;
//setter and getter
public class InterventionsModel {
    private String type;

    @JsonAdapter(LabelsDeserializer.class)
    private List<String> label;

    // Setters and getters
}
public class LabelsDeserializer implements JsonDeserializer<List<String>> {
    @Override
    public List<String> deserialize(
            final JsonElement json,
            final Type typeOfT,
            final JsonDeserializationContext context) {
        // Check if the JSON object is an array or a primitive value
        if (json.isJsonArray()) {
            // Multiple Strings elements
            final JsonArray jsonArray = json.getAsJsonArray();
            final List<String> labels = new ArrayList<>(jsonArray.size());

            for (final JsonElement jsonElement : jsonArray) {
                labels.add(jsonElement.getAsString());
            }

            return labels;
        }

        // Single String element
        return Collections.singletonList(json.getAsString());
    }
}
public class LabelsDeserializer extends TypeAdapter<List<String>> {
    @Override
    public void write(
            final JsonWriter out,
            final List<String> labels) throws IOException {
        if (labels.size() == 1) {
            out.value(labels.get(0));
            return;
        }

        out.beginArray();

        for (final String l : labels) {
            out.value(l);
        }

        out.endArray();
    }

    @Override
    public List<String> read(final JsonReader in) throws IOException {
        final JsonToken peek = in.peek();

        if (peek.equals(JsonToken.BEGIN_ARRAY)) {
            final List<String> labels = new ArrayList<>();
            in.beginArray();

            while (in.hasNext()) {
                labels.add(in.nextString());
            }

            in.endArray();
            return labels;
        }

        return Collections.singletonList(in.nextString());
    }
}