GSON是Java Throwable
我有一个包含一段数据和相关exception的对象。
Public class MyBean{ Private String data; Private Exception problem; . . . }
当我尝试GSON.toJSON(对象)时,它给我一个循环引用错误抱怨“问题”字段。
有没有办法让GSON处理这些对象?
在尝试序列化原始问题中描述的数据结构时,Gson确实会抱怨循环引用错误。
以下示例演示了这一点。
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; }
此示例导致以下exception和来自Gson的消息。
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同样会窒息。
System.out.println(new Gson().toJson(new RuntimeException("Ack!")));
Gson目前没有可用于简单解决此问题的配置。 我建议您在http://code.google.com/p/google-gson/issues/list上记录问题。
如果必须序列化具有Exception
引用的对象,并且必须使用Gson,则必须实现Exception
引用的自定义序列化处理。 以下是一个这样的例子。
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 { @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; }
输出:
{"data":"some data","problem":{"cause":"null","message":"Ack!"}}
对于它的价值, jackson在尝试序列化相同的数据结构时不会同样窒息。 Jackson将MyBean
实例序列化为JSON,如下所示。
{ "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 } ] } }
我知道这不是特定问题的答案(在2年多之前就已经正确回答)但是:
对于那些在其他情况下获得此exception的人:
尝试解析gson不知道要解析的复杂字段时发生此错误。
如果您在类中需要此字段,但不是为了解析目的而想要将其从gson解析中排除,则可以:
- 将
@Expose
注释添加到要解析的所有字段 (类似于@Expose private Long id;
) -
像这样声明Gson对象:
Gson gson = new GsonBuilder()。excludeFieldsWithoutExposeAnnotation()。create();
这对我有所帮助
GSON可以处理其他自定义类作为您的第一个类的属性,但您是否正在使用它?
gson.fromJson(yourResponse,MyBean.class)
并且Exception是您的自定义类之一? 也许如果可以与java.lang.Exception冲突。
我也在Gson 2.2.2版中面临同样的问题。 在Gson版本2.6.1中,我没有看到这个问题。
- 使用JUnit 4的预期exception机制导致意外行为的原因?
- Java Jackson:反序列化复杂的多态对象模型:JsonMappingException:意外的令牌(START_OBJECT),预期的VALUE_STRING
- 测试预期exception,exception被抛出(它显示在输出中)但是测试失败了
- throws x extends Exception方法签名
- 抛出不可能的NullPointerException
- RESTEasy Mock vs. Exception Mapper vs. Context
- 从CompletableFuture抛出exception
- 当访问的属性或方法暂时不可用时抛出什么exception?
- JSTL,Bean和方法调用