pin*_*rty 5 json duplicates gson
我在使用 GSON 解析包含时间戳作为键的 JSON 响应时遇到重复键异常。它给出了以下错误:
com.google.gson.JsonSyntaxException:重复键:1463048935 在 com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:186) 在 com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter。读(MapTypeAdapterFactory.java:141)
如何让它忽略重复条目,而只是将其解析为包含重复条目中任何一个的映射?
Hackerman 解决方案,使用 GSON v2.8.5 进行测试和工作,但使用风险自负!每当您将 GSON 更新到新版本时,请务必检查它是否仍然有效!
基本上,您可以使用通用 ObjectTypeAdapter 忽略重复项的事实,如下所示:
看起来 MapTypeAdapterFactory 检查重复项
V replaced = map.put(key, value);
if (replaced != null) {
throw new JsonSyntaxException("duplicate key: " + key);
}
Run Code Online (Sandbox Code Playgroud)
但是 ObjectTypeAdapter 不
case BEGIN_OBJECT:
Map<String, Object> map = new LinkedTreeMap<String, Object>();
in.beginObject();
while (in.hasNext()) {
map.put(in.nextName(), read(in));
}
in.endObject();
return map;
Run Code Online (Sandbox Code Playgroud)
您现在可以做的是尝试像往常一样使用反序列化fromJson,但捕获“重复键”异常,反序列化为通用对象,这将忽略重复项,再次序列化它,这将产生一个没有重复键的 JSON 字符串,最后使用其实际含义的正确类型进行反序列化。
这是一个 Kotlin 代码示例:
fun <T> String.deserialize(gson: Gson, typeToken: TypeToken<T>): T {
val type = typeToken.type
return try {
gson.fromJson<T>(this, type)
} catch (e: JsonSyntaxException) {
if (e.message?.contains("duplicate key") == true) {
gson.toJson(deserialize(gson, object : TypeToken<Any>() {})).deserialize(gson, typeToken)
} else {
throw e
}
}
}
Run Code Online (Sandbox Code Playgroud)
显然,这需要两次反序列化和一次额外的序列化,从而增加(可能会很重)开销,但目前我没有看到任何其他方法可以做到这一点。如果 Google 决定添加一个内置方式的选项来忽略重复项(如此处建议的那样),最好切换到该选项。
| 归档时间: |
|
| 查看次数: |
4758 次 |
| 最近记录: |