gson不接受json数据

时间:2018-04-10 16:49:27

标签: java json gson

我使用Wikipedia-Api下载以下JSON:

["aa",
   ["Aarhus","Aalen","Aalborg","Aargau","Aare"],
   ["","","","",""],
   ["https://wiki.openstreetmap.org/wiki/Aarhus",
    "https://wiki.openstreetmap.org/wiki/Aalen",
    "https://wiki.openstreetmap.org/wiki/Aalborg",
    "https://wiki.openstreetmap.org/wiki/Aargau",
    "https://wiki.openstreetmap.org/wiki/Aare"
   ]
]

多个在线JSON验证器接受此格式时没有任何警告甚至错误。

我的程序拒绝了这个JSON:

    class OsmWikiResult {
       private String start;
       private String[] file;
       private String[] dummy;
       private String[] link;
    }
... snip ...
    Gson gson = new Gson();
    OsmWikiResult owr = gson.fromJson(inputLine, OsmWikiResult.class);

inputLine在一行中包含整个JSON。

java -jar target/OsmWiki-1.0-jar-with-dependencies.jar xxxx
OsmWiki
getListFromOsmWiki() starting.
Url: https://wiki.openstreetmap.org/w/api.php?action=opensearch&search=aa&limit=500&namespace=0&format=json
["aa",["Aarhus","Aalen","Aalborg","Aargau","Aare"],["","","","",""],["https://wiki.openstreetmap.org/wiki/Aarhus","https://wiki.openstreetmap.org/wiki/Aalen","https://wiki.openstreetmap.org/wiki/Aalborg","https://wiki.openstreetmap.org/wiki/Aargau","https://wiki.openstreetmap.org/wiki/Aare"]]
Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:224)
    at com.google.gson.Gson.fromJson(Gson.java:888)
    at com.google.gson.Gson.fromJson(Gson.java:853)
    at com.google.gson.Gson.fromJson(Gson.java:802)
    at com.google.gson.Gson.fromJson(Gson.java:774)
    at com.wno.OsmWiki.getListFromOsmWiki(OsmWiki.java:80)
    at com.wno.OsmWiki.main(OsmWiki.java:114)
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $
    at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:385)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:213)
    ... 6 more

沃尔特

1 个答案:

答案 0 :(得分:0)

此处的问题是您尝试使用密钥startfile,{}解析数组对象 {1}}和dummy。您需要将根数组解析为link,然后从中获取单个元素。

以最简单的形式,这样的东西可以起作用:

JsonArray

我建议您创建一个自定义JsonArray root = parser.parse(inputLine).getAsJsonArray(); String searchedTerm = root.get(0).getAsString(); String[] resultTitles = gson.fromJson(root.get(1), String[].class); String[] dummy = gson.fromJson(root.get(2), String[].class); String[] links = gson.fromJson(root.get(3), String[].class); JsonDeserializer,以便只能TypeAdapter整个shebang。由于您的JSON没有非常深的嵌套,我认为您只需实现一个gson.fromJson()即可。请注意,如果您开始遇到性能问题,可能需要实现JsonDeserializer。详细了解他们的差异here

试试这个:

TypeAdapter

注意你需要如何向Gson注册反序列化器,以便它在解析import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; import com.google.gson.JsonParseException; import java.lang.reflect.Type; public class Main { public static void main(String[] args) { String inputLine = "[\"aa\",[\"Aarhus\",\"Aalen\",\"Aalborg\",\"Aargau\",\"Aare\"],[\"\",\"\",\"\",\"\",\"\"],[\"https://wiki.openstreetmap.org/wiki/Aarhus\",\"https://wiki.openstreetmap.org/wiki/Aalen\",\"https://wiki.openstreetmap.org/wiki/Aalborg\",\"https://wiki.openstreetmap.org/wiki/Aargau\",\"https://wiki.openstreetmap.org/wiki/Aare\"]]"; Gson gson = new GsonBuilder() .registerTypeAdapter(OsmWikiResult.class, new WikiSearchResultDeserializer()) .create(); OsmWikiResult result = gson.fromJson(inputLine, OsmWikiResult.class); System.out.println("result.getSearchTerm() = " + result.getSearchTerm()); System.out.println("result.getResults() = " + String.join(", ", result.getResults())); System.out.println("result.getLinks() = " + String.join(", ", result.getLinks())); } } class WikiSearchResultDeserializer implements JsonDeserializer<OsmWikiResult> { @Override public OsmWikiResult deserialize( JsonElement json, Type typeOfT, JsonDeserializationContext context ) throws JsonParseException { JsonArray root = json.getAsJsonArray(); String searchTerm = root.get(0).getAsString(); String[] results = context.deserialize(root.get(1), String[].class); String[] dummy = context.deserialize(root.get(2), String[].class); String[] links = context.deserialize(root.get(3), String[].class); return new OsmWikiResult(searchTerm, results, dummy, links); } } class OsmWikiResult { private String searchTerm; private String[] results; private String[] dummy; private String[] links; public OsmWikiResult(String searchTerm, String[] results, String[] dummy, String[] links) { this.searchTerm = searchTerm; this.results = results; this.dummy = dummy; this.links = links; } public String getSearchTerm() { return searchTerm; } public String[] getResults() { return results; } public String[] getDummy() { return dummy; } public String[] getLinks() { return links; } } 时知道该怎么做。解串器只是从API结果的数组中以正确的顺序从阵列元素中提取出来。