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

Java 使用Gson反序列化Reddit JSON时出现StackOverflowerError,java,json,gson,android,Java,Json,Gson,Android,我试图使用Gson反序列化Reddit评论页面,但我得到了stackoverflowerrror。我在谷歌上发现,这是因为JSON数据中存在循环引用。数据具有如下所示的嵌套对象 Listing:{ data:List<Comment> } Comment:{ ... replies:Listing } 列表:{ 数据:列表 } 评论:{ ... 答复:列名 } 我不确定如何准确地编写反序列化程序来处理此类数据 有人能帮我使用Gson处理上述数据吗 下面是J

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

Listing:{
    data:List<Comment>
}
Comment:{
    ...
    replies:Listing
}
列表:{
数据:列表
}
评论:{
...
答复:列名
}
我不确定如何准确地编写反序列化程序来处理此类数据

有人能帮我使用Gson处理上述数据吗

下面是JSON数据的示例URL之一:

编辑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;
    }
}
publicstaticvoidmain(字符串[]args){
GsonBuilder gb=新的GsonBuilder();
gb.registerTypeAdapter(Thing.class,newThingDeserializer());
gb.registerTypeAdapter(Comment.class,新的CustomAdapter());
Gson Gson=gb.create();
试一试{
List listing=gson.fromJson(readUrlToString(“https://www.reddit.com/r/technology/comments/6977qb/.json),新的TypeToken(){}.getType());
System.out.println(列表);
}捕获(例外e){
e、 printStackTrace();
}
}
公共类列表{
私有列表数据;
}
公共类列表数据{
私有列表子项=null;
}
公营儿童{
私人物品数据;
}
公共类注释实现{
私人上市回复;
}
公共类ThingDeserializer实现JsonDeserializer{
@凌驾
公共事物反序列化(JsonElement json,类型typeOfT,JsonDeserializationContext)抛出JsonParseException{
if(json==null)
返回null;
否则{
Thing=null;
String name=json.getAsJsonObject().get(“name”).getAsJsonPrimitive().getAsString();
if(name.startsWith(“t1_”)){
thing=context.deserialize(json,newTypeToken(){}.getType());
}
else if(name.startsWith(“t2”)){
thing=context.deserialize(json,newTypeToken(){}.getType());
}
else if(name.startsWith(“t3”)){
thing=context.deserialize(json,newTypeToken(){}.getType());
}
else if(name.startsWith(“t4”)的名称){
thing=context.deserialize(json,newTypeToken(){}.getType());
}
else if(name.startsWith(“t5”)){
thing=context.deserialize(json,newTypeToken(){}.getType());
}
归还物;
}
}
}
公共类CustomAdapter扩展了TypeAdapter{
@凌驾
公共注释读取(JsonReader JsonReader)引发IOException{
注释=新注释();
jsonReader.beginObject();
while(jsonReader.hasNext()){
if(jsonReader.peek().equals(JsonToken.NAME)){
开关(jsonReader.nextName()){
案例“答复”:
if(jsonReader.peek().equals(JsonToken.BEGIN_对象)){
jsonReader.beginObject();
Listing=新列表();
while(jsonReader.hasNext()){
开关(jsonReader.nextName()){
案例“种类”:
setKind(jsonReader.nextString());
打破
案例“数据”:
ListingData ListingData=新建ListingData();
jsonReader.beginObject();
while(jsonReader.hasNext()){
开关(jsonReader.nextName()){
“儿童”案:
jsonReader.beginArray();
List childList=new ArrayList();
while(jsonReader.hasNext()){
jsonReader.beginObject();
子项=新子项();
while(jsonReader.hasNext()){
开关(jsonReader.nextName()){
案例“数据”:
setData(read(jsonReader));
打破
违约:
jsonReader.skipValue();
打破
}
}
childList.add(child);
}
listingData.setChildren(childList);
打破
违约:
jsonReader.skipValue();
打破
}
}
listing.setData(listingData);
打破
违约:
jsonReader.skipValue();