Différence entre / et /* dans le servlet de cartographie de modèle d'url
Le familier code:
<servlet-mapping>
<servlet-name>main</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>main</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Ma compréhension est que /*
cartes à http://host:port/context/*
.
Comment sur /
? C'est sûr qu'il n'a pas de carte pour http://host:port/context
racine seulement. En fait, il va accepter http://host:port/context/hello
, mais rejeter http://host:port/context/hello.jsp
.
Quelqu'un peut-il expliquer comment est http://host:port/context/hello
mappé?
Vous devez vous connecter pour publier un commentaire.
<url-pattern>/*</url-pattern>
La
/*
sur un servlet qui écrase toutes les autres servlets, y compris toutes les servlets fournis par le servletcontainer tels que le défaut de servlet et JSP servlet. Quelle que soit la demande vous le feu, il va finir dans cette servlet. C'est donc un mauvais modèle d'URL pour les servlets. Généralement, vous souhaitez utiliser/*
sur unFiltre
seulement. Il est capable de laisser la demande de continuer à l'une des servlets à l'écoute sur un plan plus spécifique de modèle d'URL en appelantFilterChain#doFilter()
.<url-pattern>/</url-pattern>
La
/
ne pas remplacer toute autre servlet. Il ne remplace l'servletcontainer est intégré par défaut servlet pour toutes les demandes qui ne correspond pas à toutes les autres marques de servlet. Ceci est normalement appelée sur les ressources statiques (CSS/JS/image/etc) et les listes de répertoires. Le servletcontainer est intégré par défaut servlet est également capable de traiter avec le cache HTTP demandes, multimédia (audio/vidéo) en streaming et téléchargement du fichier reprend. Habituellement, vous ne voulez pas remplacer la valeur par défaut de servlet comme vous, autrement, auraient à prendre soin de toutes ses tâches, ce qui n'est pas trivial (JSF bibliothèque utilitaire OmniFaces a un open source exemple). C'est donc aussi un mauvais modèle d'URL pour les servlets. Pourquoi des pages JSP n'a pas touché à cette servlet, c'est parce que la servletcontainer du builtin JSP servlet sera invoqué, ce qui est déjà par défaut mappé sur le sujet plus spécifique de modèle d'URL*.jsp
.<url-pattern></url-pattern>
Puis il y a aussi la chaîne vide modèle d'URL
. Ce sera invoquée lorsque la racine de contexte est demandé. Ceci est différent de la
<welcome-file>
approche qu'il n'est pas invoquée lorsqu'un sous-dossier est demandé. C'est probablement le modèle d'URL que vous cherchez dans le cas où vous voulez un "la page d'accueil de servlet". Je dois avouer que j'avais attendez la chaîne vide modèle d'URLet la barre oblique modèle d'URL
/
être défini exactement le contraire, alors je peux comprendre que beaucoup de débutants suis confus sur ce point. Mais elle est ce qu'elle est.Contrôleur Frontal
Dans le cas où vous fait l'intention d'avoir un contrôleur frontal servlet, alors vous feriez mieux de le mapper sur un plan plus spécifique de modèle d'URL comme
*.html
,*.do
,/pages/*
,/app/*
, etc. Vous pouvez cacher le contrôleur frontal modèle d'URL et de couvrir les ressources statiques sur un modèle d'URL comme/resources/*
,/static/*
, etc avec l'aide d'un filtre de servlet. Voir aussi Comment prévenir les ressources statiques d'être traités par le contrôleur frontal servlet, qui est mappé sur /*. A noté devrait être que Spring MVC a un builtin ressource statique servlet, c'est pourquoi vous pourriez carte son contrôleur frontal sur/
si vous configurez une commune modèle d'URL pour les ressources statiques au Printemps. Voir aussi Comment gérer le contenu statique dans Spring MVC?/**
indique?/**
motif de suffixe est toutefois reconnaissable, à partir de la 3ème partie librairies/frameworks tels que Spring et Shiro. Consultez sa documentation pour plus de détail à la place./*
ne pas remplacer tous les autres servlets, et non pas toutes les demandes là. Le conteneur va d'abord essayer de trouver une correspondance exacte, et puis le plus long chemin de préfixe de match. Ainsi, un servlet avec la cartographie/foo/bar
ou de l'un avec la cartographie/foo/*
le feu avant qu'un servlet avec la cartographie/*
. Cependant, l'un avec/*
prévalent sur toute l'extension de la cartographie comme*.html
.J'aimerais ajouter à BalusC de réponse avec les règles de mappage et un exemple.
Règles de mappage de Servlet 2.5 spécifications:
Dans notre exemple, il y a trois servlets. /est la valeur par défaut de servlet installé par nous. Tomcat installe deux servlets pour servir jsp et jspx. Donc pour la carte
http://host:port/context/hello
À la carte
http://host:port/context/hello.jsp
Peut-être vous avez besoin de connaître la façon dont les url sont mappés aussi, puisque j'ai subi
404
pendant des heures. Il existe deux types de gestionnaires de traitement des demandes.BeanNameUrlHandlerMapping
etSimpleUrlHandlerMapping
. Lorsque nous avons défini unservlet-mapping
, nous utilisonsSimpleUrlHandlerMapping
. Une chose que nous devons savoir, c'est que ces deux gestionnaires partagent une propriété appeléealwaysUseFullPath
qui, par défaut,false
.false
signifie ici le Printemps à ne pas utiliser le chemin d'accès complet à mapp une url à un contrôleur. Ça veut dire quoi? Cela signifie que, lorsque vous définissez unservlet-mapping
:le gestionnaire utilisera en fait le
*
pour trouver le contrôleur. Par exemple, le contrôleur devra faire face à un404
d'erreur lorsque vous en faites la demande à l'aide de/perfix/api/feature/doSomething
Il est un match parfait, non? Mais pourquoi
404
. Comme mentionné précédemment, la valeur par défaut dealwaysUseFullPath
est false, ce qui signifie dans votre demande, seulement/api/feature/doSomething
est utilisé pour trouver un Contrôleur correspondant, mais il n'y a aucun Contrôleur ne se soucie que de chemin. Vous devez soit modifier votre url à/perfix/perfix/api/feature/doSomething
ou supprimerperfix
de MyController base@RequestingMapping
.Je pense que Candy réponse est la plupart du temps correct. Il y a une petite partie je pense le contraire.
À la carte d'hôte:port/contexte/bonjour.jsp
Je crois que pourquoi "/*" ne correspond pas à l'hôte:port/contexte/bonjour parce qu'il traite "/hello" comme un chemin d'accès au lieu d'un fichier (car il ne possède pas d'extension).
La différence essentielle entre
/*
et/
est qu'un servlet avec la cartographie/*
seront sélectionnés avant une servlet avec une extension de la cartographie (comme*.html
), tandis qu'un servlet avec la cartographie/
sera sélectionné uniquement après que les mappages d'extension sont considérés (et sera utilisé pour toute demande qui ne correspond pas à quelque chose d'autre---c'est le "défaut de servlet").En particulier, un
/*
cartographie sera toujours sélectionné avant un/
de cartographie. Ayant empêche toute demande d'atteindre le conteneur par défaut servlet.Sera sélectionné uniquement après servlet mappings qui sont les correspondances exactes (comme
/foo/bar
) et ceux qui sont mappages de chemin d'accès de plus de/*
(comme/foo/*
). Notez que la chaîne vide, la cartographie est une correspondance exacte pour la racine de contexte (http://host:port/context/
).Voir le Chapitre 12 de la Spécification Servlet Java, disponible dans la version 3.1 à http://download.oracle.com/otndocs/jcp/servlet-3_1-fr-eval-spec/index.html.