Différence entre / et / * dans le modèle d'url de mapping de servlet
le code familier:
<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>
je crois comprendre que /*
correspond à http://host:port/context/*
.
et /
? Il ne correspond pas seulement à la racine http://host:port/context
. En fait , elle acceptera http://host:port/context/hello
, mais rejettera http://host:port/context/hello.jsp
.
est-ce que quelqu'un peut expliquer comment http://host:port/context/hello
est cartographié?
5 réponses
<url-pattern>/*</url-pattern>
le /*
sur un servlet l'emporte sur tous les autres servlets, y compris tous les servlets fournis par le servletcontainer tels que le servlet par défaut et le servlet JSP. Quelle que soit votre requête, elle finira dans ce servlet. C'est donc un mauvais motif D'URL pour les servlets. Généralement, vous souhaitez utiliser /*
sur un Filter
. Il est capable de laisser la requête continuer vers n'importe lequel des servlets écoutant sur un modèle D'URL plus spécifique en appelant FilterChain#doFilter()
.
<url-pattern>/</url-pattern>
le /
ne remplace aucun autre servlet. Il remplace seulement le servlet par défaut du servletcontainer pour toutes les requêtes qui ne correspondent à aucun autre servlet enregistré. Ceci n'est normalement invoqué que sur les ressources statiques (CSS/JS/image/etc) et les répertoires. Le servlet par défaut du servletcontainer est également capable de traitement des requêtes de cache HTTP, de streaming de médias (audio/vidéo) et des reprises de téléchargement de fichiers. Habituellement, vous ne voulez pas surcharger le servlet par défaut car vous auriez autrement à prendre soin de toutes ses tâches, qui n'est pas exactement trivial (bibliothèque d'utilité JSF OmniFaces a un open source exemple ). C'est donc aussi un mauvais motif D'URL pour les servlets. Quant à savoir pourquoi les pages JSP n'atteignent pas ce servlet, c'est parce que le le servlet JSP intégré par servletcontainer sera invoqué, qui est déjà par défaut mappé sur le modèle D'URL plus spécifique *.jsp
.
<url-pattern></url-pattern>
puis il y a aussi l'approche . This will be invoked when the context root is requested. This is different from the
<welcome-file>
qui n'est pas invoquée lorsqu'un sous-dossier est demandé. C'est très probablement le modèle D'URL que vous recherchez réellement dans le cas où vous voulez un " servlet de page d'accueil ". Je n'ai qu'à admettez que je m'attendrais intuitivement à ce que le motif D'URL de chaîne vide
et le motif D'URL de barre oblique /
soit défini exactement dans l'autre sens, donc je peux comprendre que beaucoup de démarreurs se sont confondus sur ce point. Mais elle est ce qu'elle est.
Contrôleur Avant
dans le cas où vous en fait avoir l'intention d'avoir un servlet contrôleur frontal, alors vous feriez mieux de le mapper sur un modèle D'URL plus spécifique comme *.html
, *.do
, /pages/*
, /app/*
, etc. Vous pouvez cacher le modèle D'URL du contrôleur frontal et couvrir les ressources statiques sur un modèle D'URL commun comme /resources/*
, /static/*
, etc à l'aide d'un filtre de servlet. Voir aussi comment empêcher les ressources statiques d'être manipulées par le servlet du contrôleur front qui est mappé sur /* . Noté devrait être que le ressort MVC a un servlet de ressource statique intégré, donc c'est pourquoi vous pourriez mapper son contrôleur avant sur /
si vous configurez un modèle D'URL commun pour les ressources statiques au printemps. Voir aussi comment gérer le contenu statique en MVC de printemps?
j'aimerais compléter la réponse de BalusC avec les règles de mappage et un exemple.
règles de Mappage de Servlet 2.5 spécifications:
- Carte exacte URL
- Carte joker chemins
- extensions de carte
- Carte à la valeur par défaut de la servlet
dans notre exemple, il y a trois servlets. / est le servlet par défaut que nous avons installé. Tomcat installe deux servlets pour servir jsp et jspx. Ainsi à la carte http://host:port/context/hello
- Aucune adresse URL exacte de servlets installé, à côté.
- Pas de générique chemins de servlets installé, à côté.
- ne correspond à aucune extension, suivant.
- Carte à la valeur par défaut de la servlet, retour.
à la carte http://host:port/context/hello.jsp
- Aucune adresse URL exacte de servlets installé, à côté.
- Pas de générique chemins de servlets installé, à côté.
- trouvé servlet d'extension, retour.
peut-être avez-vous besoin de savoir comment les urls sont mappées aussi, puisque j'ai souffert 404
pendant des heures. Il existe deux types de manipulateurs qui traitent les demandes. BeanNameUrlHandlerMapping
et SimpleUrlHandlerMapping
. Lorsque nous avons défini un servlet-mapping
, nous utilisons SimpleUrlHandlerMapping
. Une chose que nous devons savoir est que ces deux gestionnaires partagent une propriété commune appelée alwaysUseFullPath
qui est par défaut à false
.
false
signifie ici que Spring n'utilisera pas le chemin complet pour mapper une url vers un controller. Ça veut dire quoi? Cela signifie que lorsque vous définissez un servlet-mapping
:
<servlet-mapping>
<servlet-name>viewServlet</servlet-name>
<url-pattern>/perfix/*</url-pattern>
</servlet-mapping>
le gestionnaire utilisera en fait le *
pour trouver le contrôleur. Par exemple, le contrôleur suivant fera face à une erreur 404
lorsque vous le demanderez en utilisant /perfix/api/feature/doSomething
@Controller()
@RequestMapping("/perfix/api/feature")
public class MyController {
@RequestMapping(value = "/doSomething", method = RequestMethod.GET)
@ResponseBody
public String doSomething(HttpServletRequest request) {
....
}
}
c'est une correspondance parfaite, non? Mais pourquoi 404
. Comme mentionné précédemment, la valeur par défaut de alwaysUseFullPath
est false, ce qui signifie dans votre demande, /api/feature/doSomething
est utilisé pour trouver un contrôleur correspondant, mais aucun contrôleur ne se soucie de ce chemin. Vous devez changer votre url en /perfix/perfix/api/feature/doSomething
ou supprimer perfix
de la base de MyController @RequestingMapping
.
je pense que la réponse de Candy est correcte. Il y a une petite partie que je pense autrement.
À la carte d'hôte:port/contexte/bonjour.jsp
- Aucune adresse URL exacte de servlets installé, à côté.
- chemin de remplacement trouvé servlets , retour.
je crois que pourquoi "/ * "ne correspond pas à host: port / context / hello parce qu'il traite "/ hello" comme un chemin au lieu d'un fichier (puisqu'il ne possède pas d'extension).
la différence essentielle entre /*
et /
est qu'un servlet avec mapping /*
sera sélectionné avant tout servlet avec mapping d'extension (comme *.html
), alors qu'un servlet avec mapping /
ne sera sélectionné qu'après que les mappings d'extension seront considérés (et sera utilisé pour toute requête qui ne correspond à rien d'autre---c'est le"servlet par défaut").
en particulier, un /*
cartographie sera toujours sélectionné avant un mapping /
. Avoir l'un ou l'autre empêche toute requête d'atteindre le propre servlet par défaut du conteneur.
sera sélectionné seulement après des mappages de servlet qui sont des Correspondances exactes (comme /foo/bar
) et ceux qui sont des mappages de chemin plus long que /*
(comme /foo/*
). Notez que la correspondance des chaînes vides correspond exactement à la racine du contexte ( http://host:port/context/
).
voir Chapitre 12 du Java Servlet Spécification, disponible dans la version 3.1 à http://download.oracle.com/otndocs/jcp/servlet-3_1-fr-eval-spec/index.html .