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