首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >gson不接受json数据

gson不接受json数据
EN

Stack Overflow用户
提问于 2018-04-11 00:49:27
回答 1查看 460关注 0票数 3

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

代码语言:javascript
复制
["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被我的程序拒绝:

代码语言:javascript
复制
    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。

代码语言:javascript
复制
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

沃尔特

EN

回答 1

Stack Overflow用户

发布于 2018-04-13 01:08:39

这里的问题是,您试图将一个数组解析为一个具有键startfiledummylink的对象。您需要将根数组解析为JsonArray,然后从中获取各个元素。

在最简单的形式下,像这样的东西将会起作用:

代码语言:javascript
复制
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);

我建议创建一个自定义的JsonDeserializerTypeAdapter,这样就可以gson.fromJson()整个过程了。由于您的JSON没有很深的嵌套,我认为您可以只实现一个JsonDeserializer。请注意,如果您开始遇到性能问题,您可能希望实现TypeAdapter。阅读更多关于他们不同之处的here

试试这个:

代码语言:javascript
复制
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; }
}

请注意,您需要向Gson注册反序列化程序,以便它知道在解析OsmWikiResult时要做什么。反序列化程序只是按照正确的顺序从API结果的数组中取出数组的元素。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49759019

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档