使用Gson反序列化Reddit JSON时出现StackOverflowError

时间:2017-05-04 22:29:45

标签: java json gson android

我正在尝试使用Gson反序列化Reddit评论页面,但我得到了StackOverflowError。从我发现谷歌搜索,这是因为JSON数据中的循环引用。数据有嵌套对象,如下所示。

Listing:{
    data:List<Comment>
}
Comment:{
    ...
    replies:Listing
}

我不确定如何编写解串器来处理这类数据。

有人可以帮助我使用Gson处理上面的数据吗?

以下是JSON数据的示例网址之一:enter image description here

编辑1:

我已根据@Lyubomyr Shaydariv的建议创建了类型适配器。以下是我的新代码。

我还无法找到优化嵌套交换机案例的方法。新代码没有给出任何错误但没有返回任何结果。

public static void main(String[] args) {
    GsonBuilder gb = new GsonBuilder();
    gb.registerTypeAdapter(Thing.class, new ThingDeserializer());
    gb.registerTypeAdapter(Comment.class, new CustomAdapter());
    Gson gson = gb.create();
    try {
        List<Listing> listing = gson.fromJson(readUrlToString("https://www.reddit.com/r/technology/comments/6977qb/.json"), new TypeToken<Collection<Listing>>() {}.getType());
        System.out.println(listing);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
public class Listing {
    private ListingData data;
}
public class ListingData {
    private List<Child> children = null;
}
public class Child {
    private Thing data;
}
public class Comment implements Thing {
    private Listing replies;
}

public class ThingDeserializer implements JsonDeserializer<Thing> {
    @Override
    public Thing deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        if (json == null)
            return null;
        else {
            Thing thing =null;
            String name=json.getAsJsonObject().get("name").getAsJsonPrimitive().getAsString();
            if(name.startsWith("t1_")){
                thing=context.deserialize(json,new TypeToken<Comment>(){}.getType());
            }
            else if(name.startsWith("t2_")){
                thing=context.deserialize(json,new TypeToken<User>(){}.getType());
            }
            else if(name.startsWith("t3_")){
                thing=context.deserialize(json,new TypeToken<Post>(){}.getType());
            }
            else if(name.startsWith("t4_")){
                thing=context.deserialize(json,new TypeToken<Message>(){}.getType());
            }
            else if(name.startsWith("t5_")){
                thing=context.deserialize(json,new TypeToken<Subreddit>(){}.getType());
            }
            return thing;
        }
    }
}
public class CustomAdapter extends TypeAdapter<Comment> {
    @Override
    public Comment read(JsonReader jsonReader) throws IOException {
        Comment comment=new Comment();
        jsonReader.beginObject();
        while(jsonReader.hasNext()) {
            if (jsonReader.peek().equals(JsonToken.NAME)) {
                switch (jsonReader.nextName()) {
                    case "replies":
                        if (jsonReader.peek().equals(JsonToken.BEGIN_OBJECT)) {
                            jsonReader.beginObject();
                            Listing listing = new Listing();
                            while (jsonReader.hasNext()) {
                                switch (jsonReader.nextName()) {
                                    case "kind":
                                        listing.setKind(jsonReader.nextString());
                                        break;
                                    case "data":
                                        ListingData listingData = new ListingData();
                                        jsonReader.beginObject();
                                        while (jsonReader.hasNext()) {
                                            switch (jsonReader.nextName()) {
                                                case "children":
                                                    jsonReader.beginArray();
                                                    List<Child> childList = new ArrayList<>();
                                                    while (jsonReader.hasNext()) {
                                                        jsonReader.beginObject();
                                                        Child child = new Child();
                                                        while (jsonReader.hasNext()) {
                                                            switch (jsonReader.nextName()) {
                                                                case "data":
                                                                    child.setData(read(jsonReader));
                                                                    break;
                                                                default:
                                                                    jsonReader.skipValue();
                                                                    break;
                                                            }
                                                        }
                                                        childList.add(child);
                                                    }
                                                    listingData.setChildren(childList);
                                                    break;
                                                default:
                                                    jsonReader.skipValue();
                                                    break;
                                            }

                                        }
                                        listing.setData(listingData);
                                        break;
                                    default:
                                        jsonReader.skipValue();
                                        break;
                                }
                            }
                            comment.setReplies(listing);
                        }
                        break;
                    default:
                        jsonReader.skipValue();
                        break;
                }
            }
        }

        return comment;
    }
}

0 个答案:

没有答案