Ihre Standard-Spring-MVC-Anwendung bedient alle Anforderungen über eine DispatcherServlet
, die Sie bei Ihrem Servlet-Container registriert haben.
Das DispatcherServlet
prüft seine ApplicationContext
und, falls verfügbar, die ApplicationContext
mit einem ContextLoaderListener
für spezielle Beans registrierten , die es benötigt, um seine Anforderungs-Serving-Logik einzurichten. Diese Beans sind in der Dokumentation beschrieben .
Die wohl wichtigsten Bohnen vom Typ HandlerMapping
Map
Eingehende Anforderungen an Handler und eine Liste von Vor- und Nachprozessoren (Handler-Interceptors) basierend auf einigen Kriterien, deren Details je nach HandlerMapping
Implementierung variieren . Die beliebteste Implementierung unterstützt kommentierte Controller, es gibt jedoch auch andere Implementierungen.
Das Javadoc vonHandlerMapping
beschreibt weiter, wie sich Implementierungen verhalten müssen.
Das DispatcherServlet
findet alle Beans dieses Typs und registriert sie in einer bestimmten Reihenfolge (kann angepasst werden). Während der Bearbeitung einer Anforderung DispatcherServlet
werden diese HandlerMapping
Objekte durchlaufen und jedes von ihnen getestet getHandler
, um eines zu finden, das die eingehende Anforderung verarbeiten kann, die als Standard dargestellt wird HttpServletRequest
. Ab 4.3.x, wenn es irgendwelche nicht finden , es protokolliert die Warnung , dass Sie sehen ,
Keine Zuordnung gefunden für HTTP - Anforderung mit URI [/some/path]
in DispatcherServlet
mit dem Namen Somenamen
und löst entweder a aus NoHandlerFoundException
oder schreibt die Antwort sofort mit einem 404 Not Found-Statuscode fest.
Warum hat das nicht DispatcherServlet
eine finden , HandlerMapping
die meine Anfrage umgehen konnte?
Die häufigste HandlerMapping
Implementierung ist RequestMappingHandlerMapping
die Registrierung von @Controller
Beans als Handler (eigentlich ihre mit @RequestMapping
Anmerkungen versehenen Methoden). Sie können eine Bean dieses Typs entweder selbst (mit @Bean
oder mit einem <bean>
anderen Mechanismus) deklarieren oder die integrierten Optionen verwenden . Diese sind:
- Kommentieren Sie Ihre
@Configuration
Klasse mit @EnableWebMvc
.
- Deklarieren Sie ein
<mvc:annotation-driven />
Mitglied in Ihrer XML-Konfiguration.
Wie der obige Link beschreibt, registrieren beide eine RequestMappingHandlerMapping
Bean (und eine Reihe anderer Dinge). Allerdings ist eine HandlerMapping
nicht sehr nützlich ist, ohne einen Handler. RequestMappingHandlerMapping
erwartet einige @Controller
Beans, daher müssen Sie diese auch deklarieren, durch @Bean
Methoden in einer Java-Konfiguration oder <bean>
Deklarationen in einer XML-Konfiguration oder durch Komponentenscannen von @Controller
annotierten Klassen in beiden. Stellen Sie sicher, dass diese Bohnen vorhanden sind.
Wenn Sie die Warnmeldung und einen 404 erhalten und alle oben genannten Punkte korrekt konfiguriert haben, senden Sie Ihre Anfrage an den falschen URI , der nicht von einer erkannten @RequestMapping
Methode für kommentierte Handler verarbeitet wird.
Die spring-webmvc
Bibliothek bietet weitere integrierte HandlerMapping
Implementierungen. Zum Beispiel BeanNameUrlHandlerMapping
Karten
von URLs zu Beans mit Namen, die mit einem Schrägstrich beginnen ("/")
und du kannst immer deine eigenen schreiben. Natürlich müssen Sie sicherstellen, dass die Anforderung, die Sie senden, mindestens einem der HandlerMapping
Handler des registrierten Objekts entspricht.
Wenn Sie keine HandlerMapping
Beans implizit oder explizit registrieren (oder wenn dies der FalldetectAllHandlerMappings
ist true
), DispatcherServlet
werden einige Standardeinstellungen registriert . Diese werden im DispatcherServlet.properties
selben Paket wie die DispatcherServlet
Klasse definiert. Sie sind BeanNameUrlHandlerMapping
und DefaultAnnotationHandlerMapping
(ähnlich, RequestMappingHandlerMapping
aber veraltet).
Debuggen
Spring MVC protokolliert registrierte Handler RequestMappingHandlerMapping
. Zum Beispiel ein @Controller
Like
@Controller
public class ExampleController {
@RequestMapping(path = "/example", method = RequestMethod.GET, headers = "X-Custom")
public String example() {
return "example-view-name";
}
}
protokolliert Folgendes auf INFO-Ebene
Mapped "{[/example],methods=[GET],headers=[X-Custom]}" onto public java.lang.String com.spring.servlet.ExampleController.example()
Dies beschreibt die registrierte Zuordnung. Wenn Sie die Warnung sehen, dass kein Handler gefunden wurde, vergleichen Sie den URI in der Nachricht mit der hier aufgeführten Zuordnung. Alle im Abschnitt angegebenen Einschränkungen @RequestMapping
müssen übereinstimmen, damit Spring MVC den Handler auswählt.
Andere HandlerMapping
Implementierungen protokollieren ihre eigenen Anweisungen, die auf ihre Zuordnungen und die entsprechenden Handler verweisen sollen.
Aktivieren Sie auf ähnliche Weise die Spring-Protokollierung auf DEBUG-Ebene, um zu sehen, welche Beans Spring registriert. Es sollte angeben, welche mit Anmerkungen versehenen Klassen gefunden werden, welche Pakete gescannt und welche Beans initialisiert werden. Wenn die erwarteten nicht vorhanden sind, überprüfen Sie Ihre ApplicationContext
Konfiguration.
Andere häufige Fehler
A DispatcherServlet
ist nur ein typischer Java EE Servlet
. Sie registrieren es mit Ihrer typischen <web.xml>
<servlet-class>
und <servlet-mapping>
Deklaration oder direkt ServletContext#addServlet
in einem WebApplicationInitializer
oder mit einem beliebigen Mechanismus, den Spring Boot verwendet. Daher müssen Sie sich auf die in der Servlet-Spezifikation angegebene URL-Zuordnungslogik verlassen , siehe Kapitel 12. Siehe auch
In diesem Sinne besteht ein häufiger Fehler darin, das DispatcherServlet
mit einer URL-Zuordnung von zu registrieren /*
, einen Ansichtsnamen von einer @RequestMapping
Handler-Methode zurückzugeben und zu erwarten, dass eine JSP gerendert wird. Betrachten Sie beispielsweise eine Handlermethode wie
@RequestMapping(path = "/example", method = RequestMethod.GET)
public String example() {
return "example-view-name";
}
mit einem InternalResourceViewResolver
@Bean
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver vr = new InternalResourceViewResolver();
vr.setPrefix("/WEB-INF/jsps/");
vr.setSuffix(".jsp");
return vr;
}
Sie könnte die Anforderung erwarten werden weitergeleitet auf dem Weg zu einer JSP Ressource /WEB-INF/jsps/example-view-name.jsp
. Das wird nicht passieren. Unter der Annahme eines Kontextnamens von wird stattdessen Example
der DisaptcherServlet
Bericht erstellt
Keine Zuordnung gefunden für HTTP - Anforderung mit URI [/Example/WEB-INF/jsps/example-view-name.jsp]
in DispatcherServlet
mit dem Namen ‚Dispatcher‘
Da das DispatcherServlet
auf alles abgebildet ist /*
und /*
mit allem übereinstimmt (mit Ausnahme von exakten Übereinstimmungen, die eine höhere Priorität haben), wird das DispatcherServlet
ausgewählt, um das forward
von dem JstlView
(von dem zurückgegebenen InternalResourceViewResolver
) zu verarbeiten. In fast allen Fällen wird der DispatcherServlet
nicht für die Verarbeitung einer solchen Anforderung konfiguriert .
In diesem vereinfachten Fall sollten Sie stattdessen das DispatcherServlet
to registrieren /
und es als Standardservlet markieren. Das Standardservlet ist die letzte Übereinstimmung für eine Anforderung. Auf diese Weise kann Ihr typischer Servlet-Container eine interne Servlet-Implementierung auswählen *.jsp
, die der JSP-Ressource zugeordnet ist (z. B. Tomcat JspServlet
), bevor Sie es mit dem Standardservlet versuchen.
Das sehen Sie in Ihrem Beispiel.
@EnableWebMvc
eine@Configuration
kommentierte Klasse das nicht. Es werden lediglich einige Standard-Spring-MVC-Handler / -Adapter-Beans zum Anwendungskontext hinzugefügt. Das Registrieren einesDispatcherServlet
Dienstes/
ist ein völlig separater Prozess, der auf verschiedene Arten durchgeführt wird, die ich im Abschnitt Andere häufige Fehler beschreibe . Ich beantworte die Frage zwei Absätze unter dem, was Sie zitiert haben.Ich habe mein Problem behoben, als zusätzlich zu den zuvor beschriebenen: `
added tomcat-embed-jasper:
`from: JSP-Datei wird in der Spring Boot-Webanwendung nicht gerendert
quelle
In meinem Fall folgte ich der Interceptors Spring-Dokumentation für Version 5.1.2 (während ich Spring Boot v2.0.4.RELEASE verwendete ) und die
WebConfig
Klasse hatte die Annotation@EnableWebMvc
, die mit etwas anderem in meiner Anwendung in Konflikt zu stehen schien, das meine statische Aufladung verhinderte Assets wurden nicht korrekt aufgelöst (dh es wurden keine CSS- oder JS-Dateien an den Client zurückgegeben).Nachdem viele verschiedene Dinge auszuprobieren, habe ich versucht , das Entfernen der
@EnableWebMvc
und es funktionierte!Bearbeiten: Hier ist die Referenzdokumentation , die besagt, dass Sie die
@EnableWebMvc
Anmerkung entfernen solltenZumindest in meinem Fall konfiguriere ich meine Spring-Anwendung anscheinend bereits (obwohl sie nicht mithilfe
web.xml
einer anderen statischen Datei verwendet wird, sondern definitiv programmgesteuert), sodass es dort zu einem Konflikt kam.quelle
Versuchen Sie, Ihren Code mit der folgenden Änderung in Ihrer Konfigurationsdatei zu ändern. Java-Konfiguration wird anstelle von verwendet
application.properties
. Vergessen Sie nicht, die Konfiguration in derconfigureDefaultServletHandling
Methode zu aktivieren .Ich benutze gradle, du solltest folgende Abhängigkeiten haben in
pom.xml
:quelle
Ich bin auf einen anderen Grund für denselben Fehler gestoßen. Dies kann auch an den Klassendateien liegen, die nicht für Ihre Datei controller.java generiert wurden. Infolgedessen kann das in web.xml erwähnte Dispatcher-Servlet es nicht der entsprechenden Methode in der Controller-Klasse zuordnen.
In Eclipse unter Projekt-> Wählen Sie Bereinigen -> Projekt erstellen. Überprüfen Sie, ob die Klassendatei für die Controller-Datei unter Builds in Ihrem Arbeitsbereich generiert wurde.
quelle
Für mich stellte ich fest, dass meine Zielklassen in einem Ordnermuster generiert wurden, das nicht mit dem Quellmuster übereinstimmt. Dies ist möglicherweise in Eclipse. Ich füge Ordner hinzu, um meine Controller zu enthalten, und füge sie nicht als Pakete hinzu. Also habe ich in der Frühjahrskonfiguration einen falschen Pfad definiert.
Meine Zielklasse generierte Klassen unter App und ich bezog mich auf com.happy.app
Ich habe Pakete (keine Ordner) für com.happy.app hinzugefügt und die Dateien aus Ordnern in Pakete in Eclipse verschoben, um das Problem zu beheben.
quelle
Reinigen Sie Ihren Server. Löschen Sie möglicherweise den Server und fügen Sie das Projekt erneut hinzu und führen Sie es aus.
Stoppen Sie den Tomcat-Server
Klicken Sie mit der rechten Maustaste auf den Server und wählen Sie "Reinigen".
Klicken Sie erneut mit der rechten Maustaste auf den Server und wählen Sie "Tomcat-Arbeitsverzeichnis bereinigen".
quelle
In meinem Fall habe ich mit dem Import von sekundären Java-Konfigurationsdateien in eine Java-Hauptkonfigurationsdatei herumgespielt. Beim Erstellen von sekundären Konfigurationsdateien hatte ich den Namen der Hauptkonfigurationsklasse geändert, aber den Namen in web.xml nicht aktualisiert. Bei jedem Neustart meines Tomcat-Servers wurden keine Mapping-Handler in der Eclipse IDE-Konsole angezeigt. Beim Versuch, zu meiner Startseite zu navigieren, wurde der folgende Fehler angezeigt:
Das Update bestand darin, die Datei web.xml so zu aktualisieren, dass der alte Name "WebConfig" stattdessen "MainConfig" lautet, und sie einfach umzubenennen, um den neuesten Namen der Java-Hauptkonfigurationsdatei wiederzugeben (wobei "MainConfig" willkürlich ist und die Wörter " Web "und" Main ", die hier verwendet werden, sind keine Syntaxanforderungen. MainConfig war wichtig, da die Datei nach "WebController" gesucht hat, meiner Spring-MVC-Controller-Klasse, die meine Webanforderungen verarbeitet.
web.xml hatte folgendes:
Die Datei web.xml hat jetzt:
Jetzt sehe ich die Zuordnung im Konsolenfenster:
Und meine Webseite wird wieder geladen.
quelle
Ich hatte das gleiche Problem wie
**No mapping found for HTTP request with URI [/some/path] in DispatcherServlet with name SomeName**
Nachdem ich 2 bis 4 Tage analysiert hatte, fand ich die Grundursache heraus. Klassendateien wurden nicht generiert, nachdem ich das Projekt ausgeführt habe. Ich habe auf die Registerkarte Projekt geklickt.
Klassendateien für den Quellcode wurden generiert. Es hat mein Problem gelöst. Um zu überprüfen, ob Klassendateien generiert wurden oder nicht, überprüfen Sie den Build-Ordner in Ihrem Projektordner.
quelle