Votre application Spring MVC standard servira toutes les demandes via un DispatcherServlet
que vous avez enregistré avec votre conteneur Servlet.
Le DispatcherServlet
regarde son ApplicationContext
et, si disponible, le ApplicationContext
enregistré avec un ContextLoaderListener
pour les beans spéciaux dont il a besoin pour configurer sa logique de traitement de demande. Ces beans sont décrits dans la documentation .
Sans doute le type de HandlerMapping
carte le plus important
les demandes entrantes aux gestionnaires et une liste de pré et post-processeurs (intercepteurs de gestionnaires) basée sur certains critères dont les détails varient selon l' HandlerMapping
implémentation. L'implémentation la plus populaire prend en charge les contrôleurs annotés, mais d'autres implémentations existent également.
Le javadoc deHandlerMapping
décrit plus en détail comment les implémentations doivent se comporter.
Le DispatcherServlet
recherche tous les beans de ce type et les enregistre dans un certain ordre (peut être personnalisé). Tout en traitant une requête, le DispatcherServlet
parcourt ces HandlerMapping
objets et teste chacun d'eux avec getHandler
pour trouver celui qui peut gérer la requête entrante, représentée comme le standard HttpServletRequest
. À partir de 4.3.x, s'il n'en trouve aucun , il enregistre l'avertissement que vous voyez
Aucune correspondance trouvée pour la requête HTTP avec l' URI [/some/path]
en DispatcherServlet
avec le nom UnNom
et soit lancers francs un NoHandlerFoundException
ou engage immédiatement la réponse avec un code d'état 404 Not Found.
Pourquoi la DispatcherServlet
recherche n'a-t-elle pas HandlerMapping
pu traiter ma demande?
L' HandlerMapping
implémentation la plus courante est RequestMappingHandlerMapping
, qui gère l'enregistrement des @Controller
beans en tant que gestionnaires (en fait leurs @RequestMapping
méthodes annotées). Vous pouvez soit déclarer vous-même un bean de ce type (avec @Bean
ou <bean>
ou un autre mécanisme), soit utiliser les options intégrées . Ceux-ci sont:
- Annotez votre
@Configuration
classe avec @EnableWebMvc
.
- Déclarez un
<mvc:annotation-driven />
membre dans votre configuration XML.
Comme le lien ci-dessus le décrit, les deux enregistreront un RequestMappingHandlerMapping
bean (et un tas d'autres choses). Cependant, a HandlerMapping
n'est pas très utile sans gestionnaire. RequestMappingHandlerMapping
attend des @Controller
beans, vous devez donc les déclarer également, via des @Bean
méthodes dans une configuration Java ou des <bean>
déclarations dans une configuration XML ou via l'analyse des composants des @Controller
classes annotées dans l'un ou l'autre. Assurez-vous que ces haricots sont présents.
Si vous recevez le message d'avertissement et un 404 et que vous avez configuré tout ce qui précède correctement, vous envoyez votre demande au mauvais URI , qui n'est pas géré par une @RequestMapping
méthode de gestionnaire annotée détectée .
La spring-webmvc
bibliothèque propose d'autres HandlerMapping
implémentations intégrées . Par exemple, des BeanNameUrlHandlerMapping
cartes
des URL aux beans dont les noms commencent par une barre oblique ("/")
et vous pouvez toujours écrire le vôtre. De toute évidence, vous devrez vous assurer que la requête que vous envoyez correspond à au moins un des HandlerMapping
gestionnaires de l' objet enregistré .
Si vous n'enregistrez pas implicitement ou explicitement de HandlerMapping
beans (ou si detectAllHandlerMappings
c'est le cas true
), les valeurs par défaut sontDispatcherServlet
enregistrées . Ceux-ci sont définis dans le même package que la classe. Ils sont et (qui est similaire mais obsolète).DispatcherServlet.properties
DispatcherServlet
BeanNameUrlHandlerMapping
DefaultAnnotationHandlerMapping
RequestMappingHandlerMapping
Débogage
Spring MVC enregistrera les gestionnaires enregistrés via RequestMappingHandlerMapping
. Par exemple, un @Controller
like
@Controller
public class ExampleController {
@RequestMapping(path = "/example", method = RequestMethod.GET, headers = "X-Custom")
public String example() {
return "example-view-name";
}
}
enregistrera ce qui suit au niveau INFO
Mapped "{[/example],methods=[GET],headers=[X-Custom]}" onto public java.lang.String com.spring.servlet.ExampleController.example()
Ceci décrit le mappage enregistré. Lorsque vous voyez l'avertissement qu'aucun gestionnaire n'a été trouvé, comparez l'URI dans le message au mappage répertorié ici. Toutes les restrictions spécifiées dans @RequestMapping
doivent correspondre pour que Spring MVC sélectionne le gestionnaire.
D'autres HandlerMapping
implémentations consignent leurs propres instructions qui devraient faire allusion à leurs mappages et à leurs gestionnaires correspondants.
De même, activez la journalisation Spring au niveau DEBUG pour voir quels beans Spring enregistre. Il doit indiquer les classes annotées qu'il trouve, les packages qu'il analyse et les beans qu'il initialise. Si ceux que vous attendiez ne sont pas présents, vérifiez votre ApplicationContext
configuration.
Autres erreurs courantes
A DispatcherServlet
est juste un Java EE typique Servlet
. Vous l'enregistrez avec votre déclaration typique <web.xml>
<servlet-class>
et <servlet-mapping>
, ou directement via ServletContext#addServlet
un WebApplicationInitializer
, ou avec n'importe quel mécanisme utilisé par Spring boot. En tant que tel, vous devez vous fier à la logique de mappage d'URL spécifiée dans la spécification du servlet , voir le chapitre 12. Voir aussi
Dans cet esprit, une erreur courante consiste à enregistrer le DispatcherServlet
avec un mappage d'URL de /*
, à renvoyer un nom de vue à partir d'une @RequestMapping
méthode de gestionnaire et à s'attendre à ce qu'une JSP soit rendue. Par exemple, considérons une méthode de gestionnaire comme
@RequestMapping(path = "/example", method = RequestMethod.GET)
public String example() {
return "example-view-name";
}
avec un InternalResourceViewResolver
@Bean
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver vr = new InternalResourceViewResolver();
vr.setPrefix("/WEB-INF/jsps/");
vr.setSuffix(".jsp");
return vr;
}
vous pouvez vous attendre à ce que la demande soit transmise à une ressource JSP sur le chemin /WEB-INF/jsps/example-view-name.jsp
. Cela n'arrivera pas. Au lieu de cela, en supposant un nom de contexte de Example
, le DisaptcherServlet
rapportera
Aucun mappage trouvé pour la requête HTTP avec l' URI [/Example/WEB-INF/jsps/example-view-name.jsp]
en DispatcherServlet
avec le nom « dispatcher »
Étant donné que le DispatcherServlet
est mappé vers /*
et /*
correspond à tout (sauf les correspondances exactes, qui ont une priorité plus élevée), le DispatcherServlet
serait choisi pour gérer le forward
depuis le JstlView
(renvoyé par le InternalResourceViewResolver
). Dans presque tous les cas, le DispatcherServlet
ne sera pas configuré pour gérer une telle demande .
Au lieu de cela, dans ce cas simpliste, vous devez enregistrer le DispatcherServlet
to /
, le marquant comme servlet par défaut. Le servlet par défaut est la dernière correspondance pour une requête. Cela permettra à votre conteneur de servlet typique de choisir une implémentation de servlet interne, mappée sur *.jsp
, pour gérer la ressource JSP (par exemple, Tomcat a JspServlet
), avant d'essayer avec le servlet par défaut.
C'est ce que vous voyez dans votre exemple.
@EnableWebMvc
sur une@Configuration
classe annotée ne fait pas cela. Tout ce qu'il fait, c'est ajouter un certain nombre de gestionnaires / adaptateurs Spring MVC par défaut au contexte de l'application. L'enregistrement d'unDispatcherServlet
service à servir/
est un processus complètement distinct qui se fait de plusieurs manières que je décris dans la section Autres erreurs courantes . Je réponds à la question posée deux paragraphes ci-dessous ce que vous avez cité.J'ai résolu mon problème en plus de ce qui a été décrit précédemment: `
added tomcat-embed-jasper:
`from: le fichier JSP ne s'affiche pas dans l'application Web Spring Boot
la source
Dans mon cas, je suivais la documentation Interceptors Spring pour la version 5.1.2 (tout en utilisant Spring Boot v2.0.4.RELEASE ) et la
WebConfig
classe avait l'annotation@EnableWebMvc
, qui semblait être en conflit avec quelque chose d'autre dans mon application qui empêchait mon statique avoir été résolus correctement (c'est-à-dire qu'aucun fichier CSS ou JS n'a été renvoyé au client).Après avoir essayé beaucoup de choses différentes, j'ai essayé de supprimer le
@EnableWebMvc
et cela a fonctionné!Modifier: voici la documentation de référence qui dit que vous devez supprimer l'
@EnableWebMvc
annotationApparemment, dans mon cas du moins, je configure déjà mon application Spring (bien que ce ne soit pas en utilisant
web.xml
ou en utilisant un autre fichier statique, c'est définitivement par programme), donc c'était un conflit là-bas.la source
Essayez de modifier votre code avec la modification suivante sur votre fichier de configuration. La configuration Java est utilisée à la place de
application.properties
. N'oubliez pas d'activer la configuration dansconfigureDefaultServletHandling
method.J'utilise gradle, vous devriez avoir les dépendances suivantes dans
pom.xml
:la source
Je suis tombé sur une autre raison pour la même erreur. Cela peut également être dû aux fichiers de classe non générés pour votre fichier controller.java. En conséquence, le servlet du répartiteur mentionné dans web.xml ne peut pas le mapper à la méthode appropriée dans la classe de contrôleur.
Dans eclipse sous Project-> sélectionnez clean -> Build Project. Vérifiez si le fichier de classe a été généré pour le fichier contrôleur sous builds dans votre espace de travail.
la source
Pour moi, j'ai trouvé que mes classes cibles étaient générées dans un modèle de dossier différent de la source. C'est peut-être dans eclipse que j'ajoute des dossiers pour contenir mes contrôleurs et ne les ajoute pas en tant que packages. J'ai donc fini par définir un chemin incorrect dans la configuration du printemps.
Ma classe cible générait des classes sous app et je faisais référence à com.happy.app
J'ai ajouté des packages (pas des dossiers) pour com.happy.app et déplacé les fichiers des dossiers vers les packages dans eclipse et cela a résolu le problème.
la source
Nettoyez votre serveur. Supprimez peut-être le serveur et ajoutez à nouveau le projet et exécutez.
Arrêtez le serveur Tomcat
Faites un clic droit sur le serveur et sélectionnez "Nettoyer"
Cliquez à nouveau avec le bouton droit sur le serveur et sélectionnez "Nettoyer le répertoire de travail Tomcat"
la source
Dans mon cas, je jouais avec l'importation de fichiers de configuration java secondaires dans un fichier de configuration java principal. Lors de la création de fichiers de configuration secondaires, j'avais changé le nom de la classe de configuration principale, mais je n'avais pas réussi à mettre à jour le nom dans web.xml. Ainsi, chaque fois que j'avais redémarré mon serveur tomcat, je ne voyais pas les gestionnaires de mappage notés dans la console Eclipse IDE, et lorsque j'ai essayé de naviguer vers ma page d'accueil, je voyais cette erreur:
Le correctif consistait à mettre à jour le fichier web.xml afin que l'ancien nom «WebConfig» soit à la place «MainConfig», en le renommant simplement pour refléter le dernier nom du fichier de configuration Java principal (où «MainConfig» est arbitraire et les mots « Web "et" Main "utilisés ici ne sont pas une condition de syntaxe) MainConfig était important, car c'était le fichier qui effectuait l'analyse des composants pour "WebController", ma classe de contrôleur mvc de printemps qui gère mes requêtes Web.
web.xml avait ceci:
Le fichier web.xml a maintenant:
Maintenant, je vois le mappage dans la fenêtre de la console:
Et ma page Web se charge à nouveau.
la source
J'ai eu le même problème que
**No mapping found for HTTP request with URI [/some/path] in DispatcherServlet with name SomeName**
Après avoir analysé pendant 2 à 4 jours, j'ai découvert la cause profonde. Les fichiers de classe n'ont pas été générés après l'exécution du projet. J'ai cliqué sur l'onglet projet.
Des fichiers de classe pour le code source ont été générés. Cela a résolu mon problème. Pour vérifier si les fichiers de classe ont été générés ou non, veuillez vérifier le dossier Build dans votre dossier de projet.
la source