首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GSON Java Throwable

GSON Java Throwable
EN

Stack Overflow用户
提问于 2011-11-16 11:42:33
回答 4查看 10.8K关注 0票数 11

我有一个对象,它包含一段数据和相关的异常。

代码语言:javascript
复制
Public class MyBean{
  Private String data;
  Private Exception problem;
.
.
.
}

当我尝试GSON.toJSON(对象)时,它会给我一个循环引用--错误,抱怨"problem“字段。

有什么办法让GSON处理这样的对象吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-11-20 05:01:30

Gson在试图序列化原始问题中描述的数据结构时确实会抱怨循环引用错误。

下面的示例演示了这一点。

代码语言:javascript
复制
import com.google.gson.Gson;

public class GsonFoo
{
  public static void main(String[] args)
  {
    MyBean bean = new MyBean();
    bean.data = "some data";
    bean.problem = new RuntimeException("Ack!");

    System.out.println(new Gson().toJson(bean));
  }
}

class MyBean
{
  public String data;
  public Exception problem;
}

此示例将导致来自Gson的以下异常和消息。

代码语言:javascript
复制
Exception in thread "main" java.lang.IllegalStateException: circular reference error
  Offending field: cause

  Offending object: preserveType: false, type: class java.lang.Throwable, obj: java.lang.RuntimeException: Ack!
    at com.google.gson.CircularReferenceException.createDetailedException(CircularReferenceException.java:43)
    at com.google.gson.JsonSerializationVisitor.visitObjectField(JsonSerializationVisitor.java:117)
...

在尝试以下简单的事情时,Gson同样会窒息。

代码语言:javascript
复制
System.out.println(new Gson().toJson(new RuntimeException("Ack!")));

Gson目前没有简单解决此问题的配置。我建议在http://code.google.com/p/google-gson/issues/list记录一个问题。

如果必须序列化具有Exception引用的对象,并且必须使用Gson,则必须实现Exception引用的自定义序列化处理。以下就是一个这样的例子。

代码语言:javascript
复制
import java.lang.reflect.Type;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;

public class GsonFoo
{
  public static void main(String[] args)
  {
    MyBean bean = new MyBean();
    bean.data = "some data";
    bean.problem = new RuntimeException("Ack!");

    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(Exception.class, new ExceptionSerializer());
    Gson gson = gsonBuilder.create();

    System.out.println(gson.toJson(bean));
  }
}

class ExceptionSerializer implements JsonSerializer<Exception>
{
  @Override
  public JsonElement serialize(Exception src, Type typeOfSrc, JsonSerializationContext context)
  {
    JsonObject jsonObject = new JsonObject();
    jsonObject.add("cause", new JsonPrimitive(String.valueOf(src.getCause())));
    jsonObject.add("message", new JsonPrimitive(src.getMessage()));
    return jsonObject;
  }
}

class MyBean
{
  public String data;
  public Exception problem;
}

输出:

代码语言:javascript
复制
{"data":"some data","problem":{"cause":"null","message":"Ack!"}}

就其价值而言,当试图序列化相同的数据结构时,杰克逊不会类似地窒息。Jackson将MyBean实例序列化为JSON,如下所示。

代码语言:javascript
复制
{
  "data":"some data",
  "problem":
  {
    "cause":null,
    "message":"Ack!",
    "localizedMessage":"Ack!",
    "stackTrace":
    [
      {
        "className":"com.stackoverflow.q8151082.JacksonFoo",
        "fileName":"JacksonFoo.java",
        "lineNumber":11,
        "methodName":"main",
        "nativeMethod":false
      }
    ]
  }
}
票数 18
EN

Stack Overflow用户

发布于 2014-11-16 12:34:27

我知道,这不是对具体问题的答案(在两年多前得到了正确的回答),但:

对于那些在其他情况下得到这一例外情况的人:

此错误发生在尝试解析gson不知道解析的复杂字段时。

如果类中需要此字段,但不需要用于解析,并且希望将其排除在gson解析之外,则可以:

  • @Expose 将注释添加到要解析的所有字段(类似于@Expose private Long id;)。
  • 声明Gson对象如下: Gson =新GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();

这正是帮助我的原因

票数 3
EN

Stack Overflow用户

发布于 2011-11-16 11:51:48

GSON可以将其他自定义类作为第一个类的属性处理,但您是否以这种方式使用它?

代码语言:javascript
复制
gson.fromJson(yourResponse,MyBean.class)

异常是您的自定义类之一吗?如果可能与java.lang.Exception发生冲突的话。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8151082

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档