2013-10-31 4 views
7

एक वस्तु आवरण प्राप्त इस जेएसओएन को एक रैपर वर्ग में मैप करें।वसंत MVC @RequestBody मैं JSON बनाने के रूप में इस के साथ गैर आदिम विशेषताओं

private class Subscription{ 
    private User manager; 
    private User userToSubscribe; 
    private String openid; 
    public User getManager() { 
     return manager; 
    } 
    public void setManager(User manager) { 
     this.manager = manager; 
    } 
    public User getUserToSubscribe() { 
     return userToSubscribe; 
    } 
    public void setUserToSubscribe(User userToSubscribe) { 
     this.userToSubscribe = userToSubscribe; 
    } 
    public String getOpenid() { 
     return openid; 
    } 
    public void setOpenid(String openid) { 
     this.openid = openid; 
    } 
} 

pom.xml में जैक्सन निर्भरता (मैं वसंत 3.1.0.RELEASE उपयोग कर रहा हूँ):

<dependency> 
     <groupId>org.codehaus.jackson</groupId> 
     <artifactId>jackson-mapper-asl</artifactId> 
     <version>1.9.10</version> 
    </dependency> 

बाकी-servlet.xml में मानचित्रण

यह आवरण है
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> 
    <property name="messageConverters"> 
     <list> 
      <ref bean="jsonConverter" /> 
     </list> 
    </property> 
</bean> 

<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> 
    <property name="supportedMediaTypes" value="application/json" /> 
</bean> 

और नियंत्रक विधि के शीर्षक:

public @ResponseBody SimpleMessage subscribeUser(@RequestBody Subscription subscription) 

POST के परिणामस्वरूप मुझे 400 गलत अनुरोध त्रुटि प्राप्त होती है। क्या ऐसा करना संभव है या मुझे @RequestBody स्ट्रिंग या @RequestBody Map<String,Object> के साथ ऐसा करने की आवश्यकता है और JSON को डीकोड करें?

धन्यवाद!

+0

ऐसा करने से आपको कुछ भी नहीं रोकना चाहिए। त्रुटि 400 अनुरोध या मैपिंग के साथ कुछ गलत बताती है। क्या 'उपयोगकर्ता' वर्ग में डिफ़ॉल्ट नो-एर्ग कन्स्ट्रक्टर है। –

+0

रैपर जावा में एक पूर्ण भिन्न अवधारणा है, आपके पास कुछ ऑब्जेक्ट्स हैं जिन्हें आप बाहरी वर्ग में एकत्र करना चाहते हैं। –

+0

आप जिस वसंत का उपयोग कर रहे हैं उसका संस्करण क्या है? –

उत्तर

3

मैं अपने स्वयं के प्रश्न का उत्तर देने जा रहा हूं। सॉटिरिओस डेलिमैनोलिस के सभी विशेष धन्यवाद क्योंकि उन्होंने यह जांचने के लिए कुंजी दी कि यह क्या हो रहा था।

कि आप जानते हैं, मैं दृश्य से निम्नलिखित json बनाएँ:

{"manager":{"username":"admin","password":"admin"},"userToSubscribe":{"username":"newuser","password":"newpassword","email":"[email protected]"},"openid":"https://myopenid..."} 

मैं इसे थोड़ा सा बदल क्योंकि मैंने महसूस किया कि एक वस्तु सदस्यता और एक वर सदस्यता बनाने के लिए आवश्यक नहीं है।आप इस तरह से JSON का निर्माण करते हैं, तो यह पूरी तरह से काम करेगा:

var manager = { 
    username: "admin", 
    password: "admin" 
}; 
var userToSubscribe = { 
    username: "newuser", 
    password: "newpassword", 
    email: "[email protected]" 
}; 

var openid = "https://myopenid..."; 

$.ajax({ 
    url: '/dp/rest/isUserSuscribed.json', 
    type: 'POST', 
    dataType: 'json', 
    contentType: 'application/json', 
    mimeType: 'application/json', 
    data: JSON.stringify({manager : manager, userToSubscribe : userToSubscribe, openid : openid}) 
}); 

नियंत्रक इस json प्राप्त करता है:

@RequestMapping(method=RequestMethod.POST, value="/isUserSuscribed.json") 
public @ResponseBody ResponseMessageElement<Boolean> isUserSuscribed(@RequestBody SubscriptionWrapper subscription){ 

और SubscriptionWrapper ...

private static class SubscriptionWrapper { 
    BasicUser manager; 
    BasicUser userToSubscribe; 
    String openid; 

    public BasicUser getManager() { 
     return manager; 
    } 
    public void setManager(BasicUser manager) { 
     this.manager = manager; 
    } 
    public BasicUser getUserToSubscribe() { 
     return userToSubscribe; 
    } 
    public void setUserToSubscribe(BasicUser userToSubscribe) { 
     this.userToSubscribe = userToSubscribe; 
    } 
    public String getOpenid() { 
     return openid; 
    } 
    public void setOpenid(String openid) { 
     this.openid = openid; 
    } 
} 

तो ... समस्या क्या है? मुझे एक गलत अनुरोध 400 त्रुटि प्राप्त हो रही थी ... मैंने मैपिंग जैक्सन 2HttpMessageConverter को सोटिरियोस के सुझाव के रूप में डीबग किया और एक अपवाद था (कोई उपयुक्त कन्स्ट्रक्टर नहीं)। जैक्सन मैपिंग एक आंतरिक वर्ग बनाने में सक्षम नहीं है कि क्या यह वर्ग स्थैतिक नहीं है। स्थिरीकरण के लिए सदस्यता रैपर सेट करना मेरी समस्या का समाधान था।

आप भी इन उत्तरों की जांच कर सकते हैं: http://stackoverflow.com/questions/8526333/jackson-error-no-suitable-constructor

http://stackoverflow.com/questions/12139380/how-to-convert-json-into-pojo-in-java-using-jackson

और अगर आप deserialize करने के लिए समस्या है, इस जाँच: http://stackoverflow.com/questions/17400850/is-jackson-really-unable-to-deserialize-json-into-a-generic-type

सभी उत्तर के लिए धन्यवाद।

2

आपको इसे स्वयं करने की आवश्यकता नहीं है। आपको अपने पोम में इस निर्भरता को जोड़ने की जरूरत है:

<dependencies> 
    <dependency> 
     <groupId>org.codehaus.jackson</groupId> 
     <artifactId>jackson-mapper-asl</artifactId> 
     <version>1.8.5</version> 
    </dependency> 
    </dependencies> 

इसके बाद वसंत आपके लिए रूपांतरण करेगा।

+0

मदद करता है हां, मेरे पास निर्भरता है। यह काम करता है अगर मैं केवल उपयोगकर्ता को भेजता हूं जिसमें उपयोगकर्ता नाम, पासवर्ड है ... लेकिन यदि मैं सदस्यता ऑब्जेक्ट भेजने की कोशिश करता हूं तो मैप नहीं किया जाता है। तो एक दृष्टिकोण यदि सब्सक्रिप्शन रैपर काम नहीं करता है तो प्रतिक्रिया बॉडी स्ट्रिंग, या रिस्पॉन्सबॉडी मैप <स्ट्रिंग, ऑब्जेक्ट> और तत्वों को प्राप्त करने और मेरी ऑब्जेक्ट्स में कनवर्ट करके इसे कर रहा है। – mannuk

+0

मुझे एक विवरण समझ में नहीं आया। आपने कहा था कि जब आप केवल उपयोगकर्ता ऑब्जेक्ट भेजते हैं (क्या आप इसे किसी अन्य यूआरएल पर भेजते हैं?) यह काम करता है, लेकिन जब आप पूरी सदस्यता भेजते हैं तो यह काम नहीं करता है। क्या ये सही है? यदि हां पहले मैपिंग यूआरएल की जांच करने का प्रयास करें, और एचटीएमएल दोबारा जेएसन सेकेंड को निर्दिष्ट सामग्री-प्रकार का पुन: उपयोग करें। – mvb13

+0

क्या आप विस्तारित कर सकते हैं कि वसंत कैसे करता है। क्या यह केवल जैक्सन एकीकरण जेएसओएन प्रारूप में परिवर्तित करना संभव है। ओपी '@ ResponseBody' के साथ मॉडल को पॉप्युलेट करने की उम्मीद करता है। –

10

आपके JSON

{ 
    "subscription": { 
     "manager": { 
      "username": "admin", 
      "password": "admin" 
     }, 
     "userToSubscribe": { 
      "username": "newuser", 
      "password": "newpassword", 
      "email": "[email protected]" 
     }, 
     "openid": "myopenid" 
    } 
} 

मूल तत्व subscription है को देखते हुए और यह एक JSON वस्तु है। आपके Subscription कक्षा में subscription फ़ील्ड नहीं है। तो subscription तत्व को मैप करने के लिए कुछ भी नहीं है और इसलिए यह 400 खराब अनुरोध के साथ विफल रहता है।

एक वर्ग SubscriptionWrapper

public class SubscriptionWrapper { 
    private Subscription subscription; 

    public Subscription getSubscription() { 
     return subscription; 
    } 

    public void setSubscription(Subscription subscription) { 
     this.subscription = subscription; 
    } 
} 

बनाएँ और अपने हैंडलर विधि बदलने के इस प्रकार के एक तर्क को स्वीकार करने के

public @ResponseBody SimpleMessage subscribeUser(@RequestBody SubscriptionWrapper subscriptionWrapper) 

आप FYI करें आप MappingJackso2nHttpMessageConverter का उपयोग करना चाहिए ObjectMapperMappingJacksonHttpMessageConverter (में विन्यस्त करने की जरूरत हो सकती है), ताकि यह गायब गुणों को अनदेखा कर सके।

+0

क्या आप अपनी आखिरी लाइनों को और अधिक समझाएंगे? ऑब्जेक्टमैपर और मैपिंग जैक्सन 2HttpMessageConverter की कॉन्फ़िगरेशन। मेरे मामले में वस्तुओं में संपत्तियों की कमी है क्योंकि वे आवश्यक नहीं हैं। – mannuk

+0

@mannuk 'मैपिंग जैक्सन 2HttpMessageConverter' पैकेज 'com.fasterxml.jackson' पैकेज के साथ नए जैक्सन पुस्तकालयों का उपयोग करता है। 'ऑब्जेक्टमैपर' में' कॉन्फ़िगरेशन() 'विधि है जिसका उपयोग आप deserialization और serialization सुविधाओं को कॉन्फ़िगर करने के लिए कर सकते हैं। आप उनमें से कुछ को देखना चाह सकते हैं। –

+0

क्या आप किसी भी वेबसाइट को जानते हैं जहां मैं इसे देख सकता हूं? मैं कनवर्टर और कॉन्फ़िगरेशन विधि के बारे में अधिक जानना चाहता हूं। मैं काम पर सोमवार को आपके उत्तर का परीक्षण करूंगा और फिर मैं आपको अपनी प्रगति – mannuk

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