gson读取具有不同结构

时间:2015-10-15 07:29:04

标签: android json gson

注意:这可以通过创建2个不同的GSON模型轻松实现,但我正在寻找解决方法。

我有一个可以处理多个JSON响应的模型。但是有一个回应:

items: [
{
kind: "youtube#playlistItem",
etag: ""fpJ9onbY0Rl_LqYLG6rOCJ9h9N8/jqbcTLu8tYm8b1FXGO14gNZrFG4"",
id: "PLUQ7I1jJqKB4lJarGcpWsP62l7iC06IkE2LDE0BxLe18",

与此相冲突(请注意具有不同类型的相同id字段。上述idString,另一个为Class):

items: [
{
kind: "youtube#searchResult",
etag: ""fpJ9onbY0Rl_LqYLG6rOCJ9h9N8/hDIU49vmD5aPhKUN5Yz9gtljG9A"",
id: {
kind: "youtube#playlist",
playlistId: "PLh6xqIvLQJSf3ynKVEc1axUb1dQwvGWfO"
},

是否可以只使用一个可以读取这两个响应的GSON模型?

非常感谢你的时间

更新

这是在Model内,我将id变量从String更改为Class

private Id id;
public class Id
{
    private String id;
    private String kind;
    private String playlistId;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getKind() {
        return kind;
    }

    public void setKind(String kind) {
        this.kind = kind;
    }

    public String getPlaylistId() {
        return playlistId;
    }

    public void setPlaylistId(String playlistId) {
        this.playlistId = playlistId;
    }
}

这就是我的请求:

        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.registerTypeAdapter(Response.class,
                new JsonDeserializer<Item.Id>() {
                    @Override
                    public Item.Id deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
                                                    if(jsonElement.isJsonObject())
                        {
                            result.setKind(jsonElement.getAsJsonObject().get("kind").getAsString());
                            result.setPlaylistId(jsonElement.getAsJsonObject().get("playlistId").getAsString());
                            //return new Item.Id(jsonElement.getAsJsonObject().get("kind").getAsString(), jsonElement.getAsJsonObject().get("playlistId").getAsString());
                            return result;
                        }
                        else
                        {
                            result.setId(jsonElement.getAsString());
                            //return new Item.Id(jsonElement.getAsString());
                            return result;
                        }
                    }
                });

1 个答案:

答案 0 :(得分:2)

问题

你只能有id表示单一类型的变量,在这种情况下,在第一个响应中你有字符串,在第二种情况下,你有一个对象,它有一个&#34; kind& #34;和一个&#34; playlistId&#34;

这似乎是后端方面的一个奇怪的设计,但它可能不在你的控制之下

<强>解决方案

你可以做的是如果你认为第一个和第二个响应中的id是相同类型的,你可以创建一个包含这些字段的封装类,如

class Id {
    private String stringId;
    private String kind;
    private String playlistId;
}

并创建一个自定义JsonDeserializer,它将基于JSON响应的类型以下列方式创建相应的Id对象:

new JsonDeserializer<Id>() {
            @Override
            public Id deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
                if(json.isJsonObject()) {
                    return new Id(json.getAsJsonObject().get("kind").getAsString(), json.getAsJsonObject().get("playlistId").getAsString());
                } else {
                    return new Id(json.getAsString());
                }
            }
        }

并在你的gson对象上注册它,因此它将处理Id字段的反序列化,并根据其类型库创建

或者你可以创建一个反序列化器来反序列化包含的对象,并根据id的类型使用不同的字段,但你应该明白这个想法!

您可以使用GsonBuilder在Gson上注册您的JsonDeserializer,并在GsonBuilder中调用registerTypeAdapter,其类型是您在以下方式注册类型适配器并使用typeadapter:

return new GsonBuilder().registerTypeAdapter(Id.class, new JsonDeserializer<Id>() {

    //..

}).build();

您可以在gson文档中了解有关自定义类型适配器的更多信息,here