【问题标题】:Gson : StackOverflowErrorGson:堆栈溢出错误
【发布时间】:2014-01-26 01:49:03
【问题描述】:

以下代码导致StackOverflowError。代码的目的是从 java 类创建一个 json 字符串。

for (ControlTransaction crt : ctrList) {
                crt= new ControlTransaction();// for test, Still issue
                final Gson gson = new GsonBuilder().registerTypeAdapter(
                ControlTransaction.class,
                  new ControlTransactionSerializer()).create();
                String jsonControlTransactionString = gson.toJson(crt);
                strList.add(jsonControlTransactionString);

            }

我的班级看起来像

public class ControlTransaction implements IsSerializable, Serializable ,IsBean{
    private long id;
    private String value; // H
    private String lastValue; // H
    private FormTransaction formTransaction;
    private List<FormTransaction> gridRows;
    private ControlTransaction referenceGridTransaction;
    private RowTransaction fkRowTransaction;
    private ReportTransaction reportTransaction;
    //getters ... setters
}

堆栈跟踪是这样的,让我知道

Caused by: java.lang.StackOverflowError
at com.google.gson.stream.JsonWriter.<init>(JsonWriter.java:190)
at com.google.gson.internal.bind.JsonTreeWriter.<init>(JsonTreeWriter.java:58)
at com.google.gson.Gson.toJsonTree(Gson.java:478)
at com.google.gson.Gson$3.serialize(Gson.java:140)
at com.nextenders.common.ControlTransactionSerializer.serialize(ControlTransactionJsonUtil.java:129)
at com.nextenders.common.ControlTransactionSerializer.serialize(ControlTransactionJsonUtil.java:1)
at com.google.gson.TreeTypeAdapter.write(TreeTypeAdapter.java:70)
at com.google.gson.Gson.toJson(Gson.java:586)
at com.google.gson.Gson.toJsonTree(Gson.java:479)
at com.google.gson.Gson$3.serialize(Gson.java:140)
at com.nextenders.common.ControlTransactionSerializer.serialize(ControlTransactionJsonUtil.java:129)
at com.nextenders.common.ControlTransactionSerializer.serialize(ControlTransactionJsonUtil.java:1)
at com.google.gson.TreeTypeAdapter.write(TreeTypeAdapter.java:70)
at com.google.gson.Gson.toJson(Gson.java:586)
at com.google.gson.Gson.toJsonTree(Gson.java:479)
at com.google.gson.Gson$3.serialize(Gson.java:140)
at com.nextenders.common.ControlTransactionSerializer.serialize(ControlTransactionJsonUtil.java:129)
at com.nextenders.common.ControlTransactionSerializer.serialize(ControlTransactionJsonUtil.java:1)
at com.google.gson.TreeTypeAdapter.write(TreeTypeAdapter.java:70)
at com.google.gson.Gson.toJson(Gson.java:586)
at com.google.gson.Gson.toJsonTree(Gson.java:479)
at com.google.gson.Gson$3.serialize(Gson.java:140)

这是我的serializerdeserializer

class ControlTransactionDeserializer implements
        JsonDeserializer<ControlTransaction> {
    @Override
    public ControlTransaction deserialize(JsonElement json, Type type,
            JsonDeserializationContext context) throws JsonParseException {
        return context.deserialize(json, type);
    }
}

class ControlTransactionSerializer implements
        JsonSerializer<ControlTransaction> {

    @Override
    public JsonElement serialize(ControlTransaction ctr, Type type,
            JsonSerializationContext context) {
        return context.serialize(ctr, type);
    }
}

后端发生了什么。我刚刚传了一个空的Object,表示新的ControlTransaction(),仍然无法解析。

【问题讨论】:

  • 让我们看看你的序列化器。
  • 你检查referenceGridTransaction是否指crt?
  • @SotiriosDelimanolis 添加了序列化器和反序列化器。

标签: java json gson stack-overflow


【解决方案1】:

JsonSerializer 的重点是序列化对象的字段,而不是对象本身。但是,您传递的是您已经告诉Gson 进行序列化的对象。以下

@Override
public JsonElement serialize(ControlTransaction ctr, Type type,
        JsonSerializationContext context) {
    return context.serialize(ctr, type);
}

等价于

@Override
public JsonElement serialize(ControlTransaction ctr, Type type,
        JsonSerializationContext context) {
    return new GsonBuilder().registerTypeAdapter(
            ControlTransaction.class,
              new ControlTransactionSerializer()).create().toJsonTree(ctr);
}

我希望你能看到它正在进入递归循环。

JsonSerializationContext 基本上是Gson 对象用来序列化对象的底层结构。当它看到您的类型ControlTransaction 时,它将委托给您的自定义JsonSerializer。但是您的JsonSerializer 会将其发送回JsonSerializationContext,然后循环继续。

【讨论】:

  • 感谢您关注该问题。你的建议是不会编译的。如果可能,请查看课程JsonDeserializer google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/… 以及那里的示例。
  • @sᴜʀᴇsʜᴀᴛᴛᴀ 我没有小心(或试图让它编译)。这只是为了让您了解JsonSerializationContext 基本上是Gson 对象用于序列化对象的底层结构。当它看到您的类型ControlTransaction 时,它将委托给您的自定义JsonSerializer。但是您的JsonSerializer 会将其发送回JsonSerializationContext,然后循环继续。
  • @sᴜʀᴇsʜᴀᴛᴛᴀ Here's 自定义序列化示例。
  • @sᴜʀᴇsʜᴀᴛᴛᴀ 你的一天的开始,我的一天的结束:) 不客气。早上好!
  • 感谢 Sotirios。晚安 :) 即使在一天结束时,你的大脑仍然很活跃。
猜你喜欢
  • 1970-01-01
  • 2015-03-28
  • 1970-01-01
  • 2019-02-16
  • 2011-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多