2011-11-16 14 views
9

मेरे पास एक ऑब्जेक्ट है जिसमें डेटा का एक टुकड़ा और संबंधित अपवाद है।जीएसओएन एक जावा थ्रोबल

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

मैं GSON.toJSON (वस्तु) करने का प्रयास करते यह मुझे एक वृत्तीय संदर्भ त्रुटि "समस्या" क्षेत्र के बारे में शिकायत कर देता है।

क्या ऐसी वस्तुओं को संभालने के लिए जीएसओएन का कोई तरीका है?

+0

किसी ऑब्जेक्ट को org.apache.log4j.Logger फ़ील्ड के साथ क्रमबद्ध करने का प्रयास करते समय मुझे एक ही समस्या का अनुभव हुआ। –

उत्तर

14

वास्तविक प्रश्न में वर्णित डेटा संरचना को क्रमबद्ध करने का प्रयास करते समय जीसन वास्तव में एक परिपत्र संदर्भ त्रुटि के बारे में शिकायत करता है।

निम्नलिखित उदाहरण इस बिंदु को दर्शाता है।

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 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) 
... 

जीसन इसी प्रकार के रूप में सरल कुछ करने का प्रयास करते समय इसी तरह चोक करता है।

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

जीसन वर्तमान में इस समस्या को हल करने के लिए कॉन्फ़िगरेशन उपलब्ध नहीं है। मैं http://code.google.com/p/google-gson/issues/list पर किसी समस्या को लॉग करने की अनुशंसा करता हूं।

यदि Exception संदर्भ वाला कोई ऑब्जेक्ट क्रमबद्ध होना चाहिए और यदि जीसन का उपयोग किया जाना चाहिए, तो 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<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; 
} 

उत्पादन:

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

क्या इसके लायक है के लिए, Jackson इसी तरह गला घोंटना नहीं है जब एक ही डेटा संरचना को क्रमानुसार करने का प्रयास कर रहा। जैक्सन ने निम्नानुसार JSON को MyBean इंस्टेंस का क्रमबद्ध किया है।

{ 
    "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

बस संदर्भ के लिए, यहां संबंधित जीसन मुद्दे का एक लिंक है: https://code.google.com/p/google-gson/issues/detail?id=469 कृपया इस मुद्दे को तारांकित करें ताकि इसे अधिक ध्यान दिया जा सके। – Simon

+0

मैं रजिस्टर टाइप के बजाय रजिस्टर टाइप टाइपरएडाएटर का उपयोग करने का सुझाव देता हूं क्योंकि आप शायद अपवाद के सभी उपप्रकारों के लिए कस्टम सीरिएलाइज़र का उपयोग करना चाहते हैं। – prasopes

+0

यह जीसन v2.3.1 में तय किया गया है – Behnil

0

जीएसओएन आपकी कस्टम कक्षा के गुणों के रूप में अन्य कस्टम वर्गों को संभाल सकता है, लेकिन क्या आप इसका उपयोग इस तरह कर रहे हैं?

gson.fromJson(yourResponse,MyBean.class) 

और अपवाद आपके कस्टम वर्ग में से एक है? शायद अगर java.lang.Exception के साथ संघर्ष में हो सकता है।

+0

अपवाद एक बीन के भीतर आयोजित एक सादा java.lang.Exception है। यह अपवाद क्षेत्र के बारे में शिकायत कर रहा है। – Ben

+0

क्या आप अपनी पोस्ट में जीसन की "शिकायत" दिखा सकते हैं? –

2

मुझे पता है कि यह विशिष्ट सवाल का जवाब नहीं है (कि अधिक से अधिक 2 साल पहले सही ढंग से उत्तर दिया गया था) लेकिन:

: जो अन्य मामलों में यह अपवाद मिल के लिए

जटिल त्रुटि को पार्स करने का प्रयास करते समय यह त्रुटि होती है कि जीसन को पार्स नहीं पता है।

यदि आप नहीं, बल्कि उद्देश्य पार्स करने के लिए अपनी कक्षा में इस क्षेत्र की जरूरत है और आप gson पार्स से बाहर करना चाहते हैं, तो आप कर सकते हैं:

  • @Expose एनोटेशन सभी क्षेत्रों में जोड़ देते हैं आप

    Gson gson = नए जी:, (@Expose private Long id; की तरह कुछ)

  • इस तरह Gson वस्तु घोषित पार्स करने के लिए चाहता हूँ । SonBuilder() excludeFieldsWithoutExposeAnnotation() बनाने()।;

है कि मुझे क्या

0

मदद की मैं भी Gson संस्करण 2.2.2 में एक ही समस्या का सामना करना पड़ रहा था। जीसन संस्करण 2.6.1 में मुझे यह समस्या नहीं दिखाई दे रही है।

संबंधित मुद्दे