आपका मानक स्प्रिंग MVC एप्लिकेशन DispatcherServlet
आपके द्वारा अपने सर्वलेट कंटेनर के साथ पंजीकृत किए गए सभी अनुरोधों को पूरा करेगा ।
DispatcherServlet
अपने दिखता है पर ApplicationContext
और, यदि उपलब्ध है, ApplicationContext
एक के साथ पंजीकृत ContextLoaderListener
विशेष सेम यह सेटअप अपने अनुरोध पेश करते तर्क की जरूरत के लिए। इन सेम को प्रलेखन में वर्णित किया गया है ।
संभवतः सबसे महत्वपूर्ण, प्रकार के HandlerMapping
नक्शे की सेम
हैंडलर के लिए आने वाले अनुरोध और कुछ मानदंडों के आधार पर प्री- और पोस्ट-प्रोसेसर (हैंडलर इंटरसेप्टर) की एक सूची, जिसके विवरण HandlerMapping
कार्यान्वयन के लिए अलग-अलग होते हैं । सबसे लोकप्रिय कार्यान्वयन एनोटेट नियंत्रकों का समर्थन करता है लेकिन अन्य कार्यान्वयन भी मौजूद हैं।
की जावाडोकHandlerMapping
आगे बताता है कि कैसे कार्यान्वयन व्यवहार करना चाहिए।
DispatcherServlet
(अनुकूलित किया जा सकता) इस प्रकार के सभी सेम पाता है और उन्हें कुछ क्रम में पंजीकृत करता है। एक अनुरोध की सेवा करते समय, DispatcherServlet
इन HandlerMapping
वस्तुओं के माध्यम से छोरों और उनमें से प्रत्येक को getHandler
एक खोजने के लिए परीक्षण करता है जो आने वाले अनुरोध को संभाल सकता है, मानक के रूप में दर्शाया गया है HttpServletRequest
। 4.3.x के रूप में, अगर यह किसी भी नहीं मिल रहा है , यह चेतावनी लॉग कि आप देख
कोई मैपिंग यूआरआई के साथ HTTP अनुरोध के लिए पाया [/some/path]
में DispatcherServlet
नाम SomeName साथ
और या तो फेंकता है NoHandlerFoundException
या तुरंत 404 Not Found स्टेटस कोड के साथ प्रतिक्रिया देता है।
ऐसा क्यों नहीं DispatcherServlet
मिला जो HandlerMapping
मेरे अनुरोध को संभाल सके?
सबसे आम HandlerMapping
कार्यान्वयन है RequestMappingHandlerMapping
, जो @Controller
बीन्स को हैंडलर के रूप में दर्ज करना संभालता है (वास्तव में उनके @RequestMapping
एनोटेट तरीके)। आप या तो स्वयं ( @Bean
या <bean>
या अन्य तंत्र के साथ) इस प्रकार की सेम की घोषणा कर सकते हैं या आप अंतर्निहित विकल्पों का उपयोग कर सकते हैं । य़े हैं:
- अपनी
@Configuration
कक्षा के साथ एनोटेट करें @EnableWebMvc
।
<mvc:annotation-driven />
अपने XML कॉन्फ़िगरेशन में एक सदस्य की घोषणा करें।
जैसा कि ऊपर दिए गए लिंक में बताया गया है, ये दोनों एक RequestMappingHandlerMapping
बीन (और अन्य सामान का एक गुच्छा) पंजीकृत करेंगे । हालांकि, HandlerMapping
एक हैंडलर के बिना बहुत उपयोगी नहीं है। RequestMappingHandlerMapping
कुछ @Controller
बीन्स की अपेक्षा करता है, इसलिए आपको @Bean
जावा कॉन्फ़िगरेशन में विधियों के माध्यम से या <bean>
एक्सएमएल कॉन्फ़िगरेशन में घोषणा या @Controller
एनोटेट कक्षाओं के घटक स्कैनिंग के माध्यम से भी घोषित करने की आवश्यकता है । सुनिश्चित करें कि ये फलियाँ मौजूद हैं।
यदि आपको चेतावनी संदेश और 404 मिल रहे हैं और आपने उपरोक्त सभी को सही तरीके से कॉन्फ़िगर किया है, तो आप अपना अनुरोध गलत यूआरआई को भेज रहे हैं , जो कि एक पता लगाए @RequestMapping
गए हैंडलर विधि द्वारा नियंत्रित नहीं किया गया है ।
spring-webmvc
अन्य पुस्तकालय प्रदान करता है निर्मित HandlerMapping
कार्यान्वयन। उदाहरण के लिए, BeanNameUrlHandlerMapping
नक्शे
स्लैश ("/") से शुरू होने वाले नामों के URL से लेकर सेम तक
और आप हमेशा अपना लिख सकते हैं। जाहिर है, आपको यह सुनिश्चित करना होगा कि आप जिस अनुरोध को पंजीकृत HandlerMapping
ऑब्जेक्ट के हैंडलर में से कम से कम एक मैच भेज रहे हैं ।
यदि आप किसी भी HandlerMapping
सेम (या यदि detectAllHandlerMappings
है true
) को स्पष्ट रूप से या स्पष्ट रूप से पंजीकृत नहीं करते हैं , तो DispatcherServlet
कुछ चूक रजिस्टर करता है । इन्हें कक्षा DispatcherServlet.properties
के समान पैकेज में परिभाषित किया गया है DispatcherServlet
। वे हैं BeanNameUrlHandlerMapping
और DefaultAnnotationHandlerMapping
(जो कि RequestMappingHandlerMapping
पदावनत के समान है )।
डिबगिंग
स्प्रिंग एमवीसी के माध्यम से पंजीकृत हैंडलर लॉग इन करेंगे RequestMappingHandlerMapping
। उदाहरण के लिए, एक @Controller
पसंद है
@Controller
public class ExampleController {
@RequestMapping(path = "/example", method = RequestMethod.GET, headers = "X-Custom")
public String example() {
return "example-view-name";
}
}
INFO स्तर पर निम्न लॉग करेगा
Mapped "{[/example],methods=[GET],headers=[X-Custom]}" onto public java.lang.String com.spring.servlet.ExampleController.example()
यह पंजीकृत मैपिंग का वर्णन करता है। जब आप यह चेतावनी देखते हैं कि कोई हैंडलर नहीं मिला, तो संदेश में URI की तुलना यहां सूचीबद्ध मैपिंग से करें। @RequestMapping
स्प्रिंग एमवीसी को हैंडलर का चयन करने के लिए निर्दिष्ट सभी प्रतिबंधों का मिलान करना चाहिए।
अन्य HandlerMapping
कार्यान्वयन अपने स्वयं के बयानों को लॉग करते हैं जो उनके मैपिंग और उनके संबंधित हैंडलर को संकेत देना चाहिए।
इसी प्रकार, स्प्रिंग को डीबग स्तर पर लॉगिंग को सक्षम करने के लिए यह देखने के लिए कि कौन सी फलियां स्प्रिंग रजिस्टर करती हैं। यह रिपोर्ट करना चाहिए कि यह किस एनोटेट वर्ग को पाता है, जो इसे स्कैन करता है, और यह किन बीन्स को आरंभ करता है। यदि आप जो उम्मीद करते हैं वह मौजूद नहीं है, तो अपने ApplicationContext
कॉन्फ़िगरेशन की समीक्षा करें ।
अन्य सामान्य गलतियाँ
A DispatcherServlet
केवल एक विशिष्ट जावा EE है Servlet
। आप इसे अपने टिपिकल <web.xml>
<servlet-class>
और <servlet-mapping>
डिक्लेरेशन के साथ, या सीधे किसी भी माध्यम ServletContext#addServlet
से WebApplicationInitializer
, या स्प्रिंग मेकेनिज्म के साथ रजिस्टर कर सकते हैं । इस प्रकार, आपको सर्वलेट विनिर्देश में निर्दिष्ट url मैपिंग तर्क पर भरोसा करना चाहिए , अध्याय 12 देखें। यह भी देखें
इसे ध्यान में रखते हुए, एक सामान्य गलती DispatcherServlet
एक यूआरएल मैपिंग के साथ रजिस्टर करना है /*
, एक @RequestMapping
हैंडलर विधि से एक दृश्य नाम वापस करना , और एक जेएसपी को प्रस्तुत करने की अपेक्षा करना। उदाहरण के लिए, एक हैंडलर विधि पर विचार करें
@RequestMapping(path = "/example", method = RequestMethod.GET)
public String example() {
return "example-view-name";
}
एक साथ InternalResourceViewResolver
@Bean
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver vr = new InternalResourceViewResolver();
vr.setPrefix("/WEB-INF/jsps/");
vr.setSuffix(".jsp");
return vr;
}
आप पथ पर एक JSP संसाधन को भेजे जाने के अनुरोध की अपेक्षा कर सकते हैं /WEB-INF/jsps/example-view-name.jsp
। ऐसा नहीं होगा। इसके बजाय, एक संदर्भ नाम मानते हुए Example
, DisaptcherServlet
रिपोर्ट करेगा
कोई मैपिंग यूआरआई के साथ HTTP अनुरोध के लिए पाया [/Example/WEB-INF/jsps/example-view-name.jsp]
में DispatcherServlet
नाम 'डिस्पैचर' के साथ
क्योंकि सभी चीज़ों के DispatcherServlet
लिए मैप किया जाता है /*
और /*
मेल खाता है (सटीक मैचों को छोड़कर, जिनकी प्राथमिकता अधिक है), को (से लौटाए गए ) से DispatcherServlet
निपटने के लिए चुना जाएगा । लगभग हर मामले में, इस तरह के अनुरोध को संभालने के लिए कॉन्फ़िगर नहीं किया जाएगा ।forward
JstlView
InternalResourceViewResolver
DispatcherServlet
इसके बजाय, इस साधारण मामले में, आप पंजीकरण करना होगा DispatcherServlet
करने के लिए /
, डिफ़ॉल्ट सर्वलेट के रूप में यह अंकन। डिफ़ॉल्ट सर्वलेट अनुरोध के लिए अंतिम मैच है। यह आपके सामान्य सर्वलेट कंटेनर को डिफ़ॉल्ट सर्वलेट के साथ प्रयास करने से पहले *.jsp
जेएसपी संसाधन (उदाहरण के लिए, टॉमकैट है JspServlet
) को संभालने के लिए मैप किए गए आंतरिक सर्वलेट कार्यान्वयन को चुनने की अनुमति देगा ।
यही आप अपने उदाहरण में देख रहे हैं।