2015-03-31 10 views
36

के बीच अंतर समझाएं मैं स्प्रिंग एमवीसी के लिए नया हूं। कृपया मुझे दस्तावेज़ों को अनपैक करने में मदद करें।स्प्रिंग एमवीसी: कृपया @RequestParam और @ModelAttribute

प्रलेखन

Spring MVC Documentation राज्यों (जोर मेरा):

  • एक विधि तर्क पर @ModelAttribute इंगित करता है तर्क मॉडल से प्राप्त किया जाना चाहिए। यदि मॉडल में मौजूद नहीं है, तो तर्क पहले तत्काल किया जाना चाहिए और फिर मॉडल में जोड़ा जाना चाहिए। एक बार मॉडल में मौजूद, तर्क के फ़ील्ड उन सभी अनुरोध पैरामीटर से पॉप्युलेट किए जाने चाहिए जिनके मिलान नाम हैं। WebDataBinder क्लास अनुरोध पैरामीटर नामों से मेल खाता है - क्वेरी स्ट्रिंग पैरामीटर और फॉर्म फ़ील्ड्स समेत - नाम के अनुसार विशेषता फ़ील्ड मॉडल।

  • @RequestParamआपके नियंत्रक में विधि पैरामीटर पर अनुरोध पैरामीटर को बाध्य करता है।

अस्वीकरण/निर्मलक

मुझे पता है कि @ModelAttribute और @RequestParam एक ही बात नहीं हैं, परस्पर अनन्य नहीं हैं, वही भूमिका प्रदर्शन नहीं करते, और एक साथ इस्तेमाल किया जा सकता है, this question में के रूप में - वास्तव में, का उपयोग @ModelAttribute के क्षेत्रों को पॉप्युलेट करने के लिए किया जा सकता है। मेरा प्रश्न उनके आंतरिक कार्यों के बीच अंतर की दिशा में अधिक तैयार है।

प्रश्न:

@ModelAttribute बीच क्या अंतर है और @RequestParam (एक विधि तर्क, नहीं विधि पर इस्तेमाल किया)? विशेष रूप से:

  • स्रोत: Do @RequestParam और @ModelAttribute जानकारी/जनसंख्या, URL में अर्थात अनुरोध पैरामीटर के एक ही स्रोत है, जो एक रूप/मॉडल है कि POST एड था के तत्वों के रूप आपूर्ति किया गया हो सकता है?
  • उपयोग: यह सही है कि @RequestParam के साथ प्राप्त चर, दूर फेंक दिया जाता है (जब तक कि एक मॉडल में पारित कर दिया) वापस कर दी है, जबकि @ModelAttribute के साथ प्राप्त चर स्वचालित रूप से मॉडल में तंग आ चुके हैं?

या बहुत ही बुनियादी कोडिंग उदाहरणों में, इन दो उदाहरणों के बीच वास्तविक कार्य अंतर क्या है?

उदाहरण 1: @RequestParam:

// foo and bar are thrown away, and are just used (e.g.) to control flow? 
@RequestMapping(method = RequestMethod.POST) 
public String testFooBar(@RequestParam("foo") String foo, 
@RequestParam("bar") String bar, ModelMap model) { 
    try { 
    doStuff(foo, bar); 
    } 
    // other code 
    } 

उदाहरण 2: @ModelAttribute:

// FOOBAR CLASS 
// Fields could of course be explicitly populated from parameters by @RequestParam 
public class FooBar{ 
    private String foo; 
    private String bar; 
    // plus set() and get() methods 
} 

// CONTROLLER 
// Foo and Bar become part of the model to be returned for the next view? 
@RequestMapping(method = RequestMethod.POST) 
public String setupForm(@ModelAttribute("fooBar") FooBar foobar) { 
    String foo = fooBar.getFoo(); 
    String bar = fooBar.getBar(); 
    try { 
     doStuff(foo, bar); 
    } 
    // other code 
} 

मेरे वर्तमान समझ:

@ModelAttribute और @RequestParam बो वें जानकारी के लिए अनुरोध पैरामीटर पूछताछ, लेकिन वे अलग तरह से इस जानकारी का उपयोग:

  • @RequestParam बस स्टैंड-अलोन चर (जो निश्चित रूप से एक @ModelAttribute कक्षा में खेतों हो सकता है) भरता है। जब नियंत्रक किया जाता है, तब तक इन चर को फेंक दिया जाएगा, जब तक उन्हें मॉडल में खिलाया नहीं जाता है।

  • @ModelAttribute एक वर्ग के क्षेत्र है, जो तब मॉडल की एक विशेषता भरता दृश्य

यह सही है करने के लिए वापस भेजा जा सके भरता है?

उत्तर

27

@RequestParam केवल स्टैंड-अलोन चर (जो निश्चित रूप से @ModelAttribute कक्षा में फ़ील्ड हो सकता है) को पॉप्युलेट करता है। जब नियंत्रक किया जाता है, तब तक इन चर को फेंक दिया जाएगा, जब तक उन्हें मॉडल में खिलाया नहीं जाता है।

सत्र के साथ "मॉडल" शब्द को भ्रमित न करें। Http बातचीत आमतौर पर है: HTTP.GET, सर्वर प्रतिक्रिया, फिर HTTP.POST। जब आपके पास उपयोग में @ModelAttribute एनोटेशन है, तो आप हमेशा जो कुछ भी एनोटेटेड करते हैं उसका एक उदाहरण बना रहे हैं, यही कारण है कि आपको लगता है कि 'मॉडल को खिलाने के लिए चीजें' चर के आसपास रह सकती हैं। यह सही नहीं है, एक बार HttpServletRequest समाप्त हो जाने के बाद उन चरों को अब ब्राउज़र/सर्वर वार्तालाप का हिस्सा नहीं बनना चाहिए जब तक उन्हें किसी सत्र में सहेजा नहीं जाता है।

@ModelAttribute एक वर्ग है, जो तब मॉडल की एक विशेषता भरता की फ़ील्ड का दृश्य

हाँ करने के लिए वापस भेजा जा सके! सही होने के लिए, @ModelAttribute स्प्रिंग को HttpServletRequest से डेटा के साथ कुछ उदाहरण के उदाहरण को पॉप्युलेट करने के लिए अपने डिफ़ॉल्ट वेब डेटा बाइंडर का उपयोग करने के लिए कहता है। इस डेटा को देखने के लिए वापस देखने का चयन प्रोग्रामर तक है। जब आपके पास @ModelAttribute के साथ एनोटेटेड विधि है, तो इसे हर बार कोडलेट को सर्वलेट कहा जाता है। जब आपके पास @ModelAttribute विधि के पैरामीटर में से एक के रूप में है, तो हम आने वाले एचटीपी फॉर्म डेटा-बाध्यकारी के बारे में बात कर रहे हैं।

कॉलिंग @RequestParamrequest.getParameter("foo") कहने के लिए एक शॉर्टकट है; हुड के तहत, जावा का HttpServletRequest आपको कुंजी-> मूल्य दिखकर अनुरोध ऑब्जेक्ट से मूल्य प्राप्त करने देता है। लौटाया गया मूल्य ऑब्जेक्ट का प्रकार है। यदि आप अपने वेब एप्लिकेशन में स्प्रिंग का उपयोग नहीं कर रहे थे तो यह वही होगा जो आप बहुत अधिक टाइप करेंगे।

वसंत तब @ModelAttribute का उपयोग शुरू करने पर इस अवशोषण को एक कदम आगे ले जाता है।यह एनोटेशन डेटा बाध्यकारी की अवधारणा को नियुक्त करता है। डेटा बाध्यकारी का लक्ष्य यह है कि आपके नियंत्रक के कोड को प्रत्येक फॉर्म तत्व के लिए request.getParameter("foo1") पर कॉल करने की आवश्यकता नहीं होगी। कल्पना करें कि आपके पास 5 फ़ील्ड के साथ एक वेब फॉर्म है। डेटा-बाइंडिंग के बिना प्रोग्रामर को मैन्युअल रूप से पुनर्प्राप्त करना होगा, और उन सभी फ़ील्ड को सत्यापित करना होगा। प्रोग्रामर को यह सुनिश्चित करना होगा कि अनुरोध में संपत्ति है, कि संपत्ति का मूल्य मौजूद है, और यह कि संपत्ति का मूल्य प्रत्येक फ़ील्ड के लिए अपेक्षित प्रकार का है। @ModelAttribute का उपयोग करके वसंत आपको यह काम करने के लिए कहता है।

आप @ModelAttribute("fooBar") FooBar fooBar के साथ अपने नियंत्रक में एक विधि व्याख्या तो FooBar का एक उदाहरण हमेशा स्प्रिंग द्वारा निर्माण किया जाएगा, और अपने विधि के लिए आपूर्ति की। जहां डेटा बाध्यकारी खेल में आता है, वह तब होता है जब यह एनोटेशन विधि के पैरामीटर में उपयोग किया जाता है; वसंत HttpServletRequest के उदाहरण को देखता है और देखता है कि यह FooBar के उदाहरण पर सही संपत्ति के अनुरोध में डेटा से मेल खाता है या नहीं। यह जावा गुण सम्मेलन से आधारित है, जहां आपके पास foo और सार्वजनिक गेटर्स और सेटर्स getFoo और setFoo नामक फ़ील्ड हैं। यह जादू प्रतीत हो सकता है लेकिन यदि आप सम्मेलन तोड़ना चाहते थे, तो आपका स्प्रिंग डेटा बाध्यकारी काम करना बंद कर देगा क्योंकि जहां आपके HttpServletRequest से डेटा को बाध्य करने के लिए आपको FooBar का उदाहरण प्राप्त होगा, लेकिन गुण अनुरोध से किसी भी मूल्य पर सेट नहीं किया जाएगा।

2

@ModelAttribute एनोटेट मापदंडों एक पंजीकृत ServletModelAttributeMethodProcessor (या ModelAttributeMethodProcessor) और @RequestParam एनोटेट पैरामीटर द्वारा नियंत्रित किया जाता है पैरामीटर प्रकार के आधार पर एक पंजीकृत RequestParamMethodArgumentResolver या RequestParamMapMethodArgumentResolver द्वारा नियंत्रित किया जाता है।

दोनों मामलों में, @ModelAttribute और @RequestParam, मूल्यों से प्राप्त किए गए हैं बाध्य होने के लिए:

यहाँ कैसे स्प्रिंग इन HandlerMethodArgumentResolvers का उपयोग करता है अपने हैंडलर विधियों के लिए तर्क को हल करने की व्याख्या दी गई ServletRequest parameters

आप ऊपर वर्णित प्रकार के स्रोत कोड देख सकते हैं, लेकिन यहां सरल विवरण दिए गए हैं।

@ModelAttribute के लिए, वसंत पैरामीटर प्रकार का एक उदाहरण बनायेगा। यह उस उदाहरण के फ़ील्ड का निरीक्षण करेगा और @ModelAttribute नाम और फ़ील्ड नामों से बना नामकरण/उपनाम रणनीति के आधार पर पैरामीटर मानों को बाध्य करने का प्रयास करेगा। यह आमतौर पर Converter उदाहरणों में से एक समूह का उपयोग करता है (पैरामीटर मान हमेशा String मान रहे हैं) जो कुछ भी लक्ष्य फ़ील्ड प्रकार Integer, Date, आदि आप अनुरूप रूपांतरण के लिए अपने स्वयं के Converter प्रकार रजिस्टर कर सकते हैं करने के लिए String से कन्वर्ट करने के लिए। आप पीओजेओ प्रकार भी घोंसला कर सकते हैं।

@RequestParam के लिए, वसंत पैरामीटर मानों से सीधे एनोटेटेड पैरामीटर प्रकार में कनवर्ट करने के लिए उसी Converter उदाहरणों का उपयोग करेगा।

ध्यान दें कि पैरामीटर मान "फेंक दिए गए" नहीं हैं। वे कंटेनर के अनुरोध प्रसंस्करण चक्र की अवधि के लिए HttpServletRequest में संग्रहीत हैं। आप उन्हें appropriate methods के माध्यम से हमेशा एक्सेस कर सकते हैं।

0

@ModelAttribute(पैरामीटर) एक मॉडल विशेषता @SessionAttributes से या @ModelAttribute(विधि) से लोड करता है।

आपको अनुरोध से मूल्यों को बाध्य करने की आवश्यकता नहीं है, लेकिन यह @SessionAttributes से लोड होने के बाद ऐसा करेगा।

@RequestParam किसी ऑब्जेक्ट को अनुरोध पैरामीटर बांधता है।

0
  • विधि स्तर

पर जब एनोटेशन विधि स्तर पर प्रयोग किया जाता है यह इंगित करता है कि विधि के प्रयोजन के लिए एक या अधिक मॉडल विशेषताएं जोड़ने पर है। ऐसी विधियां @RequestMapping विधियों के समान तर्क प्रकारों का समर्थन करती हैं लेकिन अनुरोधों पर सीधे मैप नहीं किया जा सकता है।

@ModelAttribute 
public void addAttributes(Model model) { 
    model.addAttribute("msg", "Welcome to the Netherlands!"); 
} 

एक विधि है कि एक विशेषता सभी मॉडलों के नियंत्रक वर्ग में परिभाषित करने के लिए संदेश नामित कहते हैं।

वसंत-एमवीसी हमेशा किसी भी अनुरोध हैंडलर विधियों को कॉल करने से पहले उस विधि को पहले कॉल करेगा। यही है, @MequelAttribute विधियों को @RequestMapping के साथ एनोटेटेड नियंत्रक विधियों से पहले बुलाया जाता है। अनुक्रम के पीछे तर्क यह है कि, किसी भी प्रसंस्करण नियंत्रक विधियों के अंदर शुरू होने से पहले मॉडल ऑब्जेक्ट बनाया जाना चाहिए।

यह भी महत्वपूर्ण है कि आप संबंधित वर्ग को @ControllerAdvice के रूप में एनोटेट करें। इस प्रकार, आप मॉडल में मूल्य जोड़ सकते हैं जिसे वैश्विक के रूप में पहचाना जाएगा। इसका वास्तव में मतलब है कि प्रत्येक अनुरोध के लिए प्रतिक्रिया भाग में प्रत्येक विधि के लिए डिफ़ॉल्ट मान मौजूद है।

  • एक विधि तर्क

जब एक विधि तर्क के रूप में उपयोग किया जाता है, यह इंगित करता है तर्क मॉडल से प्राप्त किया जाना चाहिए। यदि उपस्थित नहीं है, तो इसे पहले तत्काल स्थापित किया जाना चाहिए और फिर मॉडल में जोड़ा गया और मॉडल में एक बार उपस्थित होना चाहिए, तर्क फ़ील्ड मिलान नामों वाले सभी अनुरोध पैरामीटर से पॉप्युलेट किए जाने चाहिए।

उपयोगकर्ता मॉडल विशेषता का पालन करने वाले कोड स्निपेट में एडयूसर एंडपॉइंट पर सबमिट किए गए फॉर्म से डेटा के साथ पॉप्युलेट किया गया है। वसंत MVC पर्दे के पीछे से करता है विधि प्रस्तुत लागू करने से पहले:

**@RequestMapping**(value = "/addUser", method = RequestMethod.POST) 
public String submit(@ModelAttribute("user") User user) { 
    return "userView"; 
} 

इसलिए, यह एक सेम के साथ प्रपत्र डेटा बांधता है। @RequestMapping के साथ एनोटेटेड नियंत्रक में @ModelAttribute के साथ एनोटेटेड कस्टम क्लास तर्क हो सकता है।

यह आमतौर पर स्प्रिंग-एमवीसी में डेटा बाइंडिंग के रूप में जाना जाता है, यह एक सामान्य तंत्र है जो आपको प्रत्येक फॉर्म फ़ील्ड को व्यक्तिगत रूप से पार्स करने से बचाता है।

1

@ModelAttribute: एक संपूर्ण जावा ऑब्जेक्ट (जैसे कर्मचारी) को बांधता है।का समर्थन करता है एकाधिक अनुरोध पैरामीटर

@RequestParam: एक ही अनुरोध पैरामीटर (firstName की तरह)

सामान्य में बांधता है,
@RequestParam पैरामीटर की एक छोटी संख्या को पढ़ने के लिए सबसे अच्छा है।

@ModelAttribute का उपयोग तब किया जाता है जब आपके पास बड़ी संख्या में फ़ील्ड होते हैं।

और

@ModelAttribute इस तरह के डेटा बाइंडिंग, सत्यापन और प्रपत्र भरण-पूर्व के रूप में आप अतिरिक्त सुविधाओं देता है।

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