【发布时间】:2021-06-12 05:41:25
【问题描述】:
我有一个来自外部 API 的 json 对象,该对象具有以下形式的对象“列表”:
{
"width": 10,
"height": 20
"pointData": {
"0": {
"x": 7,
"y": 5,
...
},
"1": {
"x": 4,
"y": 20,
...
},
"2": {
"x": 1,
"y": 3,
...
},
...
}
}
我的反序列化器和 POJO 看起来像这样:
class KeyedListDeserializer<T> implements JsonDeserializer<List<T>> {
@Override
public List<T> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject jsonObject = json.getAsJsonObject();
List<T> things = new ArrayList<>();
int key = 0;
while (jsonObject.has(String.valueOf(key))) {
JsonElement element = jsonObject.get(String.valueOf(key));
T value = context.deserialize(element, new TypeToken<T>(){}.getType());
things.add(value);
key += 1;
}
return things;
}
}
class PointDataKeyedList extends KeyedListDeserializer<PointData> {}
class Canvas {
int width;
int height;
@JsonAdapter(PointDataKeyedList.class)
List<PointData> pointData;
...
}
class PointData {
int x;
int y;
...
}
由于pointData 对象的所有键都只是索引,我想我可以将其反序列化为列表而不是映射。运行时,Gson 成功通过反序列化,但是当我尝试访问点数据时,我得到:
Exception in thread "main" java.lang.ClassCastException: class com.google.gson.internal.LinkedTreeMap cannot be cast to class PointData (com.google.gson.internal.LinkedTreeMap and PointData are in unnamed module of loader 'app')
我不确定这里出了什么问题。我读过一些关于类型擦除的内容,这是我在搜索这个问题时经常听到的,但我并不是很了解。
【问题讨论】:
-
"pointData": {}是数组的无效表示;只需替换为[]并解析它。 -
你在哪里声明
KeyedList和KeyedListDeserializer之间的关系? (什么是KeyedList?) -
@njzk2 哎呀,我在尝试将我的实际代码转换为问题时打错了字。
KeyedList应该是KeyedListDeserializer。我称它为KeyedList,因为它在技术上是一张地图,但键只是索引,所以它基本上是一个列表。我编辑了问题中的代码 -
@MartinZeitler json 来自外部 API。我不能修改它
-
为什么不能修改字符串?您可能已经错过了关于“输入清理”的章节......这将使解析/映射它变得更加容易,例如。直接到
ArrayList<PointData>,不用再乱来了。
标签: java json gson json-deserialization