GSON - 解析特定的JSON

时间:2017-02-07 23:19:57

标签: android json gson retrofit2

如何在Retrofit(GSON)中解析它?

["football",["football","football skills","football vines","football fails","football manager 2017","football challenge","football respect","football manager 2017 download","football factory","football daily"]]

这是一个包含一个字符串和另一个数组的数组。 没有对象,只有数组。 如何在模型中表示?

这是服务器: http://suggestqueries.google.com/complete/search?client=firefox&ds=yt&q=Query

我尝试将JSON用于POJO但它什么也没有返回。

2 个答案:

答案 0 :(得分:0)

@MoQ是对的,json错了,因为它不是一个对象。你需要把它包在里面,比如{“list”:[“足球”,[“足球”,“足球技巧”,“橄榄球藤蔓”,“足球失败”,“足球经理2017”,“足球挑战”, “足球方面”,“足球经理2017下载”,“足球工厂”,“足球日报”]]}

它称为JavaScript 对象表示法。

答案 1 :(得分:0)

Gson非常棒,并且真正允许应用自定义反序列化策略,或者实现适用于不是非常用户友好的JSON结构的适配器。假设您可以使用以下自定义映射来搜索查询结果:

final class Suggestions {

    final String query;
    final List<String> suggestions;

    Suggestions(final String query, final List<String> suggestions) {
        this.query = query;
        this.suggestions = suggestions;
    }

}

编写自定义JsonDeserializer(将其视为Java对象/值转换器的JSON),您可以在其中定义如何解析给定的JSON有效负载并将其转换为Suggestions类实例:

final class SuggestionsJsonDeserializer
        implements JsonDeserializer<Suggestions> {

    private static final JsonDeserializer<Suggestions> suggestionsJsonDeserializer = new SuggestionsJsonDeserializer();

    private static final Type listOfStringsType = new TypeToken<List<String>>() {
    }.getType();

    private SuggestionsJsonDeserializer() {
    }

    static JsonDeserializer<Suggestions> getSuggestionsJsonDeserializer() {
        return suggestionsJsonDeserializer;
    }

    @Override
    public Suggestions deserialize(final JsonElement jsonElement, final Type type, final JsonDeserializationContext context)
            throws JsonParseException {
        if ( !jsonElement.isJsonArray() ) {
            throw new JsonParseException("The given JSON is not an array");
        }
        final JsonArray jsonArray = jsonElement.getAsJsonArray();
        final int length = jsonArray.size();
        if ( length != 2 ) {
            throw new JsonParseException("The given JSON array length is " + length);
        }
        final JsonElement e0 = jsonArray.get(0);
        final JsonElement e1 = jsonArray.get(1);
        final String query;
        final List<String> suggestions;
        if ( e0.isJsonPrimitive() && e1.isJsonArray() ) {
            // If the JSON array is [query, suggestions]
            query = e0.getAsJsonPrimitive().getAsString();
            suggestions = context.deserialize(e1.getAsJsonArray(), listOfStringsType);
            // e1.getAsJsonArray() call is unnecessary because the context would throw an exception if it would be not an array
            // But just make it explicit and "more symmetric" to the object destructuring around
            // Another way might be not delegating the string list parsing to context, but building a string list out of the JSON array of strings manually
        } else if ( e0.isJsonArray() && e1.isJsonPrimitive() ) {
            // If the JSON array elements are swapped like [suggestions, query]
            query = e1.getAsJsonPrimitive().getAsString();
            suggestions = context.deserialize(e0.getAsJsonArray(), listOfStringsType);
        } else {
            throw new JsonParseException("Unexpected JSON array structure");
        }
        return new Suggestions(query, suggestions);
    }

}

下一步是让Gson了解你的映射及其JSON解串器对:

final Gson gson = new GsonBuilder()
        .registerTypeAdapter(Suggestions.class, getSuggestionsJsonDeserializer())
        .create();

不使用Retrofit进行测试

    final Suggestions suggestions = gson.fromJson(JSON, Suggestions.class);
    out.println(suggestions.query);
    out.println(suggestions.suggestions);

将输出:

  

足球
  [足球,足球技巧,足球葡萄藤,足球失败,足球经理2017,足球挑战,足球方面,足球经理2017下载,足球工厂,足球日报]

为了让Retrofit了解您的自定义Gson个实例,您只需在Retrofit.Builder注册.addConverterFactory(GsonConverterFactory.create(gson))进行改造2,或.setConverter(new GsonConverter(gson))进行改造1 (如果我没错的话)。