Java 使用Gson反序列化Reddit JSON时出现StackOverflowerError
我试图使用Gson反序列化Reddit评论页面,但我得到了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
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();