2012-12-15 24 views
6

मैं (जैक्सन 1.9.11 और RestTemplate 1.0.1 के साथ) JSON, जिसमें एक क्षेत्र अधिक प्रकार अर्थ हो सकता है deserialize करने के लिए, उदाहरण के लिए करना चाहते हैं:deserializing JSON

{"responseId":123,"response":"error"} 

या

{"responseId":123,"response":{"foo":"bar", ... }} 

या तो एक या अन्य मामले विशिष्ट प्रकार (स्ट्रिंग आयुध डिपो कस्टम रिस्पांस वर्ग) में से एक सेटर के साथ ठीक से काम करता है, लेकिन जब मैं अपने इकाई सेम ओवरराइड सेटर में डाल दोनों ही मामलों को संभालने के लिए सक्षम होने के लिए, अपवाद फेंक दिया जाता है :

Caused by: org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [xxxx.templates.ExportResponse] and content type [application/json;charset=utf-8] 

मैं के बारे में तीन समाधान में सोच रहा था, लेकिन मैं उनमें से किसी को काम करने नहीं मिला: अगर यह बराबर नहीं है

  • कि स्ट्रिंग unmarshall के लिए एक ही स्ट्रिंग सेटर और अंदर उपयोग ObjectMapper का उपयोग कर, करने के लिए "त्रुटि" , लेकिन जब वह जेएस ऐरे आता है, तो यह स्ट्रिंग नहीं है इसलिए स्ट्रिंग सेटर का उपयोग नहीं किया जाता है :(।
  • अपने जेसनडेसरियललाइज़र एक्सटेंशन के साथ पॉलिमॉर्फिक प्रकार हैंडलिंग (@JsonTypeInfo एनोटेशन) का उपयोग करें - मैं अभी भी इसे समझने और कार्यान्वित करने की कोशिश कर रहा हूं।
  • HttpMessageConverter की सूची बनाएं और सभी संदेश कन्वर्टर्स के अंदर डालें, मैं इसका उपयोग कर सकता हूं। लेकिन मुझे लगता है कि यह कदम अनावश्यक है, क्योंकि केवल मैपिंग जैक्सन एचटीपी मैसेज कनवर्टर का उपयोग किया जाता है, क्या मैं सही हूँ?

संपादित करें: यह कैसे काम करता है अब

इकाई सेम में सेटर:

@JsonDeserialize(using = ResponseDeserializer.class) 
public void setResponse(Object responseObject) { 
    if(responseObject instanceof Response) 
     response = (Response) responseObject; 
} 

deserialize विधि ResponseDeserializer में:

public Response deserialize(JsonParser parser, DeserializationContext context) throws IOException, JsonProcessingException { 
    Response response = new Response(); 

    if(JsonToken.START_OBJECT.equals(parser.getCurrentToken())) { 
     ObjectMapper mapper = new ObjectMapper(); 
     response = mapper.readValue(parser, Response.class); 
    } else 
     throw new JsonMappingException("Unexpected token received."); 

    return response; 
} 
+0

मैं तुम्हें सर्वर साइड के लिए जैक्सन पार्सर का उपयोग करने की सलाह देते हैं JSON ऑब्जेक्ट्स का हेरफेर –

+0

मैं क्लाइंट साइड पर काम कर रहा हूं, सर्वर मेरा व्यवसाय नहीं है :( – shmoula

उत्तर

7

कि प्राप्त करने के लिए एक ही रास्ता एक प्रयोग है कस्टम deserializer। यहाँ

ObjectMapper mapper = new ObjectMapper(); 
SimpleModule testModule = new SimpleModule("MyModule", new Version(1, 0, 0, null)); 
testModule.addDeserializer(Response.class, new ResponseJsonDeserializer()); 
mapper.registerModule(testModule); 

और (मैं इसे कैसे कम से कम लिखते थे) कैसे लिखना है deserializer:

यहाँ एक उदाहरण है

class ResponseJsonDeserializer extends JsonDeserializer<Response> { 
    @Override 
    public Responsedeserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { 
    Response response = new Response(); 
    if(jp.getCurrentToken() == JsonToken.VALUE_STRING) { 
     response.setError(jp.getText()); 
    } else { 
     // Deserialize object 
    } 
    return response; 
    } 
} 

class Response { 
    private String error; 
    private Object otherObject; // Use the real type of your object 

    public boolean isError() { 
     return error != null; 
    } 

    // Getters and setters 

} 
+0

मैं सहमत हूं, मैं इसे कुछ ऐसा करने की कोशिश कर रहा हूं, जैसा कि मैंने लिखा था (@JsonDeserialize के साथ (= ResponseDataDeserializer.class का उपयोग करके)), इसलिए यदि मैं इसे चलाता हूं, तो मैं आपका उत्तर चिह्नित करूंगा :) – shmoula

+0

ठीक है, यह उस तरह से काम करता है, मूल प्रश्न से जुड़ा कार्य कोड। धन्यवाद। – shmoula