2015-04-08 4 views
5

मैं अध्ययन कर रहा हूं कि स्प्रिंग हैंडल REST वेब सेवाएं और मुझे HttpMessageConverter की अवधारणा से संबंधित कुछ संदेह हैं।वास्तव में @RequestBody एनोटेशन कैसे काम करता है और यह HttpMessageConverter इंटरफ़ेस से कैसे संबंधित है?

आधिकारिक दस्तावेज पर मैं पढ़ सकते हैं:

रणनीति इंटरफ़ेस है कि एक कनवर्टर कि से और HTTP अनुरोध और प्रतिक्रियाओं को परिवर्तित कर सकते हैं निर्दिष्ट करता है।

तो HttpMessageConverter एक अंतरफलक प्रतीत हो रहा है, लेकिन एक रणनीति इंटरफ़ेस वास्तव में क्या है? क्या रणनीति पैटर्न से संबंधित कुछ है या नहीं?

तो से है कि मैं क्या है समझ में वसंत स्वचालित रूप से कुछ डिफ़ॉल्ट रूप से पंजीकृत कार्यान्वयन प्रदान जब @EnableWebMvc या

का उपयोग कर लेकिन क्या वास्तव में इन कार्यान्वयन करता है? क्या आप मुझे एक व्यावहारिक उदाहरण प्रदान कर सकते हैं?

मुझे लगता है कि यह इस तरह से काम करता है:

उदाहरण के लिए एक ग्राहक प्रदर्शन एक HttpRequest इस अनुरोध को एक JSON संदेश के मुख्य भाग में डाल (मैं बहुत व्यावहारिक नहीं हूँ, लेकिन मुझे लगता है कि मैं कुछ कर सकते हैं इस तरह), तो इस JSON संदेश को मॉडल ऑब्जेक्ट में कनवर्ट करने के लिए इस HttpRequst को नियंत्रित करने वाले नियंत्रक HttpMessageConverter के कार्यान्वयन का उपयोग करते हैं। मुझे लगता है कि यह भी विपरीत है।

क्या मेरा तर्क सही है या क्या मुझे कुछ याद आ रही है?

एक और संदेह @RequestBody एनोटेशन से संबंधित है (जो मुझे लगता है कि यह पिछले विषय से संबंधित है)।

मैं इस उदाहरण है:

@RequestMapping(value="/orders/{id}", method=RequestMethod.PUT) 
@ResponseStatus(HttpStatus.NO_CONTENT) // 204 
public void updateOrder(@RequestBody Order updatedOrder, @PathVariable("id") long id) { 
    // process updated order data and return empty response 
    orderManager.updateOrder(id, updatedOrder); 
} 

तो मुझे लगता है कि @RequestBody आदेश updatedOrder के शरीर से updatedOrder इनपुट पैरामीटर का मान लेने HttpRequest और फिर साथ परिवर्तित एक में HttpMessageConverter के कार्यान्वयन का उपयोग कर ऑर्डर ऑब्जेक्ट करें।

क्या यह सही है या क्या मुझे कुछ याद आ रही है? यदि यह सही है तो सही कनवर्टर कैसे चुना जा सकता है?

उदाहरण के लिए यहाँ मैं पिछले एक के लिए समान एक और उदाहरण पाया: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html

@Controller 
@RequestMapping(value = "/pets", method = RequestMethod.POST, consumes="application/json") 
public void addPet(@RequestBody Pet pet, Model model) { 
    // implementation omitted 
} 

मुझे लगता है कि यह स्पष्ट रूप से निर्दिष्ट किया जाता है यहाँ है कि यह वस्तु कनवर्टर मॉडल के लिए एक JSON का उपयोग करना होगा। पिछले उदाहरण में क्यों निर्दिष्ट नहीं है? सही कनवर्टर कैसे चुना जा सकता है?

Tnx

उत्तर

9

हैंडलर विधि मानकों वसंत के HandlerMethodArgumentResolver और हैंडलर विधि वापसी मान द्वारा उत्पन्न कर रहे स्प्रिंग के HandlerMethodReturnValueHandler द्वारा कार्रवाई की जाती है। कार्यान्वयन जो @ResponseBody और @RequestBody दोनों से संबंधित है RequestResponseBodyMethodProcessor है।

इनमें से एक डिफ़ॉल्ट रूप से HttpMessageConverter उदाहरणों की डिफ़ॉल्ट सूची के साथ पंजीकृत है (@EnableWebMvc कॉन्फ़िगरेशन)। यह WebMvcConfigurationSupport#addDefaultHttpMessageConverters(List) में किया जाता है। आप स्रोत कोड पा सकते हैं और देख सकते हैं कि कौन से जोड़े जोड़े गए हैं और किस क्रम में।

जब वसंत एक @RequestBody पैरामीटर के लिए एक तर्क उत्पन्न करने के लिए चला जाता है, यह HttpMessageConverter उदाहरणों के माध्यम से लूप होता है, जांच करता है कि उदाहरण के HttpMessageConverter#canRead सामग्री प्रकार अनुरोध में दी गई है और यदि पैरामीटर प्रकार का एक उदाहरण उत्पन्न कर सकते हैं। यदि ऐसा हो सकता है, तो वसंत एक तर्क उत्पन्न करने के लिए HttpMessageConverter का उपयोग करेगा। यदि ऐसा नहीं हो सकता है, तो वसंत इसे छोड़ देगा और अगले उदाहरण को तब तक कोशिश करेगा जब तक कि यह खत्म न हो जाए। उस बिंदु पर, यह एक अपवाद फेंक देगा।

@ResponseBody के लिए, प्रक्रिया स्प्रिंग को छोड़कर HttpMessageConverter#canWrite का उपयोग करने के समान ही है। यह जांच करेगा कि HttpMessageConverter रिटर्न प्रकार को क्रमबद्ध कर सकता है और प्रतिक्रिया सामग्री उत्पन्न कर सकता है जो प्रतिक्रिया में अपेक्षित सामग्री प्रकार को फिट करता है (Accept अनुरोध शीर्षलेख में दिया गया है)।

@RequestParam

@RequestMapping(value = "/pets", method = RequestMethod.POST, consumes="application/json") 

की consumes विशेषता रणनीति ऊपर घोषित के साथ कोई संबंध नहीं है। केवल एक चीज है कि consumes हैंडलर के मैपिंग को प्रतिबंधित करना है। उदाहरण के लिए, इन दो संचालकों

@RequestMapping(value = "/pets", method = RequestMethod.POST) 

@RequestMapping(value = "/pets", method = RequestMethod.POST, consumes="application/json") 

पहले एक ले किसी भी सामग्री प्रकार के साथ /pets के लिए किसी भी अनुरोध को पूरा कर सकते हैं। दूसरा सामग्री /pets पर सामग्री अनुरोध application/json के साथ केवल उन अनुरोधों को संभाल सकता है।

+3

बिल्कुल सही व्याख्या, आप एक निंजा हैं, आपके लिए अंतहीन – AndreaNobili

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