Gson/Retrofit 解析变量 JSON
Gson/Retrofit parse variable JSON
我正在努力将具有可变内容的 JSON 对象解析为 Java 对象。
通常,我会尝试将 JSON 对象映射到 POJO,但是在这种情况下我不知道该怎么做。
我的 JSON 看起来像这样:
"parts": [
[
"text",
"http://www.example.com/"
],
[
"page",
[
"http://www.example.com/",
"\n\t\n\t\t\n\t\t\tSome of the Page Content preview here...",
"",
"/path/to/picture.jpg"
]
],
[
"text",
"Another String here "
]
]
运行 通过典型的 Json 到 Java 对象转换器的这段代码不起作用,因为它不能映射到简单的 POJO。
我尝试转换为 List<List<String>>> myObject;
但正如预期的那样,这给了我一个例外:
W: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_ARRAY at line 1 column 9563 path $[3]./object.parts[1][1]
我想我必须为此创建一个自定义 DeSerializer,但我不知道从哪里开始。
如能为我指明正确的方向,我们将不胜感激。
编辑:正如评论中所指出的,JSON 数据不是以有效的键值对形式提供的。我已经联系了 API 供应商,他们会解决这个问题。
在我找到在前端处理这个问题的方法之前,我会保持这个问题开放。
第二个数组元素中的第二个元素也是您发布的 JSON 中的一个数组。
由于 GSON 需要一个字符串列表列表,因此无法从此时开始解析文档。
"parts": [
...,
[
"page",
[ <--- Problematic array begin
"http://www.example.com/",
"\n\t\n\t\t\n\t\t\tSome of the Page Content preview here...",
"",
"/path/to/picture.jpg"
]
],
...
]
您的 JSON 格式不正确,我尝试将您发布的 JSON 检查到 Online JSON Formatter 上,但它无法解析您的 JSON。您需要将 JSON 封装在大括号内,如下所示:
{"parts": [
[
"text",
"http://www.example.com/"
],
[
"page",
[
"http://www.example.com/",
"\n\t\n\t\t\n\t\t\tSome of the Page Content preview here...",
"",
"/path/to/picture.jpg"
]
],
[
"text",
"Another String here "
]
]
}
JSON 将被在线 JSON 格式化程序成功解析,您应该能够很好地解析它。问题是你必须处理很多 JSON Array
而没有任何 key
来识别它们。由于 "page"
字符串后的 JSON Array
,映射它会很麻烦。
如果我建议的 JSON 可以映射到 List<List<String>>
POJO,您将必须获取第二个元素并再次手动解析它,因为第二个数组中仍然有一个数组.
希望这对您有所帮助,祝您好运!!!
此致,
里德
所以在几天后再次查看这个问题后,我终于找到了适合我的情况的解决方案!
而不是像我第一次尝试那样将元素解析为 String
。我现在将数据存储到一个简单的 java.lang.Object
我的模型现在看起来像这样:
@SerializedName("parts")
@Expose
private List<List<Object>> parts = new ArrayList<List<Object>>();
这可以防止 GSON 解析过程在检测到无效数组时使应用程序崩溃。
当尝试访问数据时,我现在检查对象是否属于 String
类型,如果是这种情况我继续,忽略所有数组。
在我的代码中,它看起来像这样:
(在我的例子中,我只需要 parts 数组中第一个元素的文本属性)
List<List<Object>> partList = myParsedObject.getParts();
if (partList.size() > 0) {
if (partList.get(0).size() > 1) {
if (partList.get(0).get(1) instanceof String) {
return partList.get(0).get(1).toString();
}
}
}
我正在努力将具有可变内容的 JSON 对象解析为 Java 对象。
通常,我会尝试将 JSON 对象映射到 POJO,但是在这种情况下我不知道该怎么做。
我的 JSON 看起来像这样:
"parts": [
[
"text",
"http://www.example.com/"
],
[
"page",
[
"http://www.example.com/",
"\n\t\n\t\t\n\t\t\tSome of the Page Content preview here...",
"",
"/path/to/picture.jpg"
]
],
[
"text",
"Another String here "
]
]
运行 通过典型的 Json 到 Java 对象转换器的这段代码不起作用,因为它不能映射到简单的 POJO。
我尝试转换为 List<List<String>>> myObject;
但正如预期的那样,这给了我一个例外:
W: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_ARRAY at line 1 column 9563 path $[3]./object.parts[1][1]
我想我必须为此创建一个自定义 DeSerializer,但我不知道从哪里开始。
如能为我指明正确的方向,我们将不胜感激。
编辑:正如评论中所指出的,JSON 数据不是以有效的键值对形式提供的。我已经联系了 API 供应商,他们会解决这个问题。
在我找到在前端处理这个问题的方法之前,我会保持这个问题开放。
第二个数组元素中的第二个元素也是您发布的 JSON 中的一个数组。
由于 GSON 需要一个字符串列表列表,因此无法从此时开始解析文档。
"parts": [
...,
[
"page",
[ <--- Problematic array begin
"http://www.example.com/",
"\n\t\n\t\t\n\t\t\tSome of the Page Content preview here...",
"",
"/path/to/picture.jpg"
]
],
...
]
您的 JSON 格式不正确,我尝试将您发布的 JSON 检查到 Online JSON Formatter 上,但它无法解析您的 JSON。您需要将 JSON 封装在大括号内,如下所示:
{"parts": [
[
"text",
"http://www.example.com/"
],
[
"page",
[
"http://www.example.com/",
"\n\t\n\t\t\n\t\t\tSome of the Page Content preview here...",
"",
"/path/to/picture.jpg"
]
],
[
"text",
"Another String here "
]
]
}
JSON 将被在线 JSON 格式化程序成功解析,您应该能够很好地解析它。问题是你必须处理很多 JSON Array
而没有任何 key
来识别它们。由于 "page"
字符串后的 JSON Array
,映射它会很麻烦。
如果我建议的 JSON 可以映射到 List<List<String>>
POJO,您将必须获取第二个元素并再次手动解析它,因为第二个数组中仍然有一个数组.
希望这对您有所帮助,祝您好运!!!
此致,
里德
所以在几天后再次查看这个问题后,我终于找到了适合我的情况的解决方案!
而不是像我第一次尝试那样将元素解析为 String
。我现在将数据存储到一个简单的 java.lang.Object
我的模型现在看起来像这样:
@SerializedName("parts")
@Expose
private List<List<Object>> parts = new ArrayList<List<Object>>();
这可以防止 GSON 解析过程在检测到无效数组时使应用程序崩溃。
当尝试访问数据时,我现在检查对象是否属于 String
类型,如果是这种情况我继续,忽略所有数组。
在我的代码中,它看起来像这样: (在我的例子中,我只需要 parts 数组中第一个元素的文本属性)
List<List<Object>> partList = myParsedObject.getParts();
if (partList.size() > 0) {
if (partList.get(0).size() > 1) {
if (partList.get(0).get(1) instanceof String) {
return partList.get(0).get(1).toString();
}
}
}