2011-11-16 37 views
9

Tôi có một đối tượng chứa một phần dữ liệu và ngoại lệ liên quan.GSON một Java Throwable

Public class MyBean{ 
    Private String data; 
    Private Exception problem; 
. 
. 
. 
} 

Khi tôi cố gắng GSON.toJSON (object) nó mang lại cho tôi một tài liệu tham khảo tròn lỗi phàn nàn về lĩnh vực "vấn đề".

Có cách nào để GSON xử lý các đối tượng như vậy không?

+0

Tôi gặp phải sự cố tương tự khi cố gắng sắp xếp một đối tượng bằng trường org.apache.log4j.Logger. –

Trả lời

14

Gson thực sự phàn nàn về lỗi tham chiếu vòng tròn khi cố gắng tuần tự hóa cấu trúc dữ liệu như được mô tả trong câu hỏi gốc.

Ví dụ sau minh họa điểm này.

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; 
} 

Ví dụ này dẫn đến ngoại lệ và thông báo sau từ 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 tương tự chokes khi cố gắng đơn giản như sau.

System.out.println(new Gson().toJson(new RuntimeException("Ack!"))); 

Gson hiện không có cấu hình để giải quyết vấn đề này. Tôi khuyên bạn nên ghi lại sự cố tại số http://code.google.com/p/google-gson/issues/list.

Nếu một đối tượng có tham chiếu Exception phải được tuần tự hóa và nếu phải sử dụng Gson, thì việc xử lý tuần tự hóa tùy chỉnh cho tham chiếu Exception phải được triển khai. Sau đây là một ví dụ.

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; 
} 

đầu ra:

{"data":"some data","problem":{"cause":"null","message":"Ack!"}} 

Đối với những gì nó có giá trị, Jackson không tương tự như nghẹt thở khi cố gắng serialize cấu trúc dữ liệu tương tự. Jackson serializes một ví dụ MyBean đến JSON như sau.

{ 
    "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 
     } 
    ] 
    } 
} 
+0

Chỉ để tham khảo, dưới đây là liên kết đến vấn đề Gson tương ứng: https://code.google.com/p/google-gson/issues/detail?id=469 Vui lòng gắn dấu sao vấn đề để nó được chú ý hơn. – Simon

+0

Tôi đề nghị sử dụng registerTypeHierarchyAdapter thay vì registerTypeAdapter vì bạn có thể muốn sử dụng serializer tùy chỉnh cho tất cả các kiểu con của Ngoại lệ. – prasopes

+0

Điều này đã được sửa trong Gson v2.3.1 – Behnil

0

GSON có thể xử lý các lớp tùy chỉnh khác làm thuộc tính của lớp học đầu tiên của bạn, nhưng bạn có đang sử dụng nó theo cách đó không?

gson.fromJson(yourResponse,MyBean.class) 

và là ngoại lệ một trong các lớp tùy chỉnh của bạn? Có lẽ nếu có thể xung đột với java.lang.Exception.

+0

Ngoại lệ được tổ chức bên trong bean là một java.lang.Exception đơn giản. nó đang phàn nàn về chính trường Ngoại lệ. – Ben

+0

Bạn có thể hiển thị trong bài đăng của mình là "Khiếu nại" của Gson không? –

2

Tôi biết rằng nó không phải là câu trả lời cho các câu hỏi cụ thể (đã được trả lời một cách chính xác trước khi hơn 2 năm) Nhưng:

cho những ai được ngoại lệ này trong các trường hợp khác:

lỗi này xảy ra khi cố phân tích cú pháp trường phức tạp mà gson không biết phân tích cú pháp.

nếu bạn cần lĩnh vực này trong lớp học của bạn, nhưng không phải cho phân tích mục đích và bạn muốn loại trừ nó ra khỏi phân tích gson, bạn có thể:

  • thêm @Expose chú thích cho tất cả các lĩnh vực mà bạn muốn phân tích, (cái gì đó như @Expose private Long id;)
  • khai báo đối tượng Gson như thế này:

    Gson gson = new G sonBuilder(). excludeFieldsWithoutExposeAnnotation(). create();

đó là những gì giúp tôi

0

Tôi cũng đã phải đối mặt với cùng một vấn đề trong Gson phiên bản 2.2.2. Trong phiên bản Gson 2.6.1 tôi không thấy vấn đề này.

Các vấn đề liên quan