Standart Spring MVC uygulamanız, DispatcherServletServlet konteynerinize kaydettiğiniz bir aracılığıyla tüm talepleri karşılayacaktır .
DispatcherServletOnun en bakar ApplicationContextve varsa, ApplicationContextbir kayıtlı ContextLoaderListenero kurulum kendi isteği sunma mantığı gereken özel fasulye için. Bu çekirdekler belgelerde açıklanmaktadır .
Muhtemelen en önemli, fasulye türü HandlerMappingharita
işleyicilere gelen istekler ve ayrıntıları HandlerMappinguygulamaya göre değişen bazı kriterlere göre ön ve son işlemcilerin (işleyici engelleyicileri) listesi . En popüler uygulama açıklamalı denetleyicileri destekler ancak başka uygulamalar da mevcuttur.
Bir JavadocHandlerMapping ileri uygulamaları davranması gerektiğini açıklamaktadır.
DispatcherServletBu türdeki tüm fasulye bulur ve bazı sırayla kaydeder (özelleştirilebilir). Bir istek sunarken, DispatcherServletbu HandlerMappingnesneler arasında döngüler oluşturur getHandlerve standart olarak temsil edilen gelen isteği işleyebilecek birini bulmak için her birini test eder HttpServletRequest. 4.3.x'ten itibaren bulamazsa , gördüğünüz uyarıyı günlüğe kaydeder.
Hiçbir haritalama URI ile HTTP isteğinde bulundu [/some/path]yılında DispatcherServletadı SomeName ile
ve ya bir atar NoHandlerFoundExceptionya da yanıtı 404 Bulunamadı durum koduyla hemen tamamlar.
Neden vermedi DispatcherServletbir bulmak HandlerMappingbenim isteği ele verebilir?
En yaygın HandlerMappinguygulama, fasulyelerin işleyiciler olarak RequestMappingHandlerMappingkaydedilmesidir @Controller(aslında @RequestMappingaçıklamalı yöntemler). Ya kendin (bu tip bir fasulye ilan edebilir @Beanveya <bean>veya başka bir mekanizma) ya da kullanabilirsiniz seçenekleri yerleşik . Bunlar:
- İle
@Configurationsınıfınıza açıklama ekleyin @EnableWebMvc.
<mvc:annotation-driven />XML yapılandırmanızda bir üye bildirin .
Yukarıdaki bağlantıda açıklandığı gibi, her ikisi de bir RequestMappingHandlerMappingfasulyeyi (ve bir sürü başka şeyi) kaydedecek . Ancak, HandlerMappingbir işleyici olmadan a pek kullanışlı değildir. RequestMappingHandlerMappingbazı @Controllerfasulye beklediğinden , bunları da @Beanbir Java yapılandırmasındaki yöntemler veya <bean>bir XML yapılandırmasındaki bildirimler yoluyla veya @Controllerher ikisinde de açıklamalı sınıfların bileşen taraması yoluyla bildirmeniz gerekir . Bu fasulyelerin mevcut olduğundan emin olun.
Uyarı mesajını ve bir 404 alıyorsanız ve yukarıdakilerin tümünü doğru şekilde yapılandırdıysanız , isteğinizi tespit edilen @RequestMappingek açıklamalı bir işleyici yöntemi tarafından işlenmeyen yanlış URI'ye gönderiyorsunuz demektir .
spring-webmvcKütüphane teklifler diğer yerleşik HandlerMappinguygulamalar. Örneğin BeanNameUrlHandlerMappingharitalar
URL'lerden eğik çizgiyle ("/") başlayan adlara kadar
ve her zaman kendi yazabilirsin. Açıkçası, gönderdiğiniz talebin kayıtlı HandlerMappingnesnenin işleyicilerinden en az biriyle eşleştiğinden emin olmanız gerekir .
Örtük veya açık herhangi kayıt sen yoksa HandlerMappingfasulye (veya eğer detectAllHandlerMappingsolduğunu true), DispatcherServletkayıtlarını bazı varsayılan . Bunlar sınıfla DispatcherServlet.propertiesaynı pakette tanımlanır DispatcherServlet. Bunlar BeanNameUrlHandlerMappingve DefaultAnnotationHandlerMapping(benzer RequestMappingHandlerMappingancak kullanımdan kaldırılmış).
Hata ayıklama
Spring MVC, üzerinden kaydedilen işleyicileri günlüğe kaydeder RequestMappingHandlerMapping. Örneğin, bir @Controllerbeğeni
@Controller
public class ExampleController {
@RequestMapping(path = "/example", method = RequestMethod.GET, headers = "X-Custom")
public String example() {
return "example-view-name";
}
}
INFO düzeyinde aşağıdakileri günlüğe kaydedecek
Mapped "{[/example],methods=[GET],headers=[X-Custom]}" onto public java.lang.String com.spring.servlet.ExampleController.example()
Bu, kaydedilen eşleştirmeyi tanımlar. İşleyici bulunamadığına dair uyarıyı gördüğünüzde, mesajdaki URI'yi burada listelenen eşlemeyle karşılaştırın. @RequestMappingİşleyiciyi seçmek için Spring MVC'de belirtilen tüm kısıtlamalar eşleşmelidir.
Diğer HandlerMappinguygulamalar, eşlemelerine ve karşılık gelen işleyicilerine ipucu vermesi gereken kendi ifadelerini günlüğe kaydeder.
Benzer şekilde, Bahar'ın hangi fasulyeleri kaydettiğini görmek için DEBUG düzeyinde Bahar günlüğünü etkinleştirin. Hangi açıklamalı sınıfları bulduğunu, hangi paketleri taradığını ve hangi çekirdekleri başlattığını rapor etmelidir. Beklediğiniz mevcut değilse, ApplicationContextyapılandırmanızı gözden geçirin .
Diğer yaygın hatalar
A DispatcherServlet, tipik bir Java EE'dir Servlet. Senin tipik ile Bunu kayıt <web.xml> <servlet-class>ve <servlet-mapping>beyan veya doğrudan aracılığıyla ServletContext#addServletbir yer WebApplicationInitializer, ya da her türlü mekanizma Bahar önyükleme kullanımları. Bu nedenle, Servlet belirtiminde belirtilen url eşleme mantığına güvenmeniz gerekir , Bölüm 12'ye bakın. Ayrıca bkz.
Bunu akılda tutarak, yaygın bir hata, DispatcherServletbir url eşlemesi ile kaydetmek, /*bir @RequestMappingeylemci yönteminden bir görünüm adı döndürmek ve bir JSP'nin işlenmesini beklemektir. Örneğin, bir işleyici yöntemi düşünün.
@RequestMapping(path = "/example", method = RequestMethod.GET)
public String example() {
return "example-view-name";
}
bir ile InternalResourceViewResolver
@Bean
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver vr = new InternalResourceViewResolver();
vr.setPrefix("/WEB-INF/jsps/");
vr.setSuffix(".jsp");
return vr;
}
isteğin yoldaki bir JSP kaynağına iletilmesini bekleyebilirsiniz /WEB-INF/jsps/example-view-name.jsp. Bu olmayacak. Bunun yerine, bir bağlam adı varsayılarak Example, DisaptcherServletwill rapor
Hiçbir haritalama URI ile HTTP isteğinde bulundu [/Example/WEB-INF/jsps/example-view-name.jsp]yılında DispatcherServletadı 'memuru' ile
Çünkü DispatcherServleteşleştirilmiş /*ve /*(daha yüksek önceliğe sahip tam eşleme, hariç) her şeyi maçları, DispatcherServletişlemek için seçileceğini forwarddan JstlView(tarafından döndürülen InternalResourceViewResolver). Hemen hemen her durumda, DispatcherServletböyle bir talebi karşılayacak şekilde yapılandırılmayacaktır .
Bunun yerine, bu basit durumda, kayıt olmalıdır DispatcherServletTo /varsayılan servlet olarak işaretlemeyi. Varsayılan sunucu uygulaması, bir istek için son eşleşmedir. Bu, tipik sunucu uygulaması kapsayıcınızın , varsayılan sunucu uygulamasını denemeden önce *.jspJSP kaynağını (örneğin Tomcat sahip JspServlet) işlemek için eşlenen bir dahili Servlet uygulamasını seçmesine olanak tanır .
Örneğinizde gördüğünüz bu.