Comment sont servlet url mappings dans le web.xml utilisé?
j'ai une toile.fichier xml avec contenu:
<servlet>
<servlet-name>servlet1</servlet-name>
<servlet-class>org.mycompany.test1</servlet-class>
</servlet>
<servlet>
<servlet-name>servlet2</servlet-name>
<servlet-class>org.mycompany.test2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servlet1</servlet-name>
<url-pattern>/path/test</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>servlet2</servlet-name>
<url-pattern>/path/test/*</url-pattern>
</servlet-mapping>
j'ai essayé les demandes
.../path/test/abc
.../path/test
les deux requêtes sont traitées par Servlet2. Pourquoi?
mise à JOUR
Merci les gars pour votre aide. J'ai réalisé que le comportement dépend de l'ordre de servlet-mapping déclaration. J'ai essayé ce site web.xml
<servlet>
<servlet-name>servlet1</servlet-name>
<servlet-class>org.mycompany.test1</servlet-class>
</servlet>
<servlet>
<servlet-name>servlet2</servlet-name>
<servlet-class>org.mycompany.test2</servlet-class>
</servlet>
<servlet>
<servlet-name>servlet3</servlet-name>
<servlet-class>org.mycompany.test3</servlet-class>
</servlet>
<servlet>
<servlet-name>servlet4</servlet-name>
<servlet-class>org.mycompany.test4</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servlet1</servlet-name>
<url-pattern>/path/test</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>servlet2</servlet-name>
<url-pattern>/path/test/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>servlet3</servlet-name>
<url-pattern>/path/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>servlet4</servlet-name>
<url-pattern>/path</url-pattern>
</servlet-mapping>
résultats:
.../path/test/abc - servlet2
.../path/test/ - servlet2
.../path/test - servlet2
.../path/abc - servlet3
.../path/ - servlet4
.../path - servlet4
2 réponses
De Servlet 3.0 cahier des charges , c'est comment le conteneur web doit localiser la servlet après la réception d'une demande (l'emphase est mienne):
le chemin utilisé pour la mise en correspondance vers un servlet est L'URL de la requête objet demande moins le chemin de contexte et le chemin de paramètres. Le Les règles de mappage de chemin D'URL ci-dessous sont utilisées dans l'ordre. le premier succès la correspondance est utilisée sans autre correspondance tentée :
- le conteneur tentera de trouver une correspondance exacte du chemin de la requête au chemin du servlet. Un match réussi sélectionne le servlet.
- le conteneur tentera de façon récursive de correspondre au plus long chemin-préfixe. Ceci est fait en descendant l'arbre de chemin un répertoire à un moment, en utilisant le caractère ’/’ comme séparateur de chemin. La plus longue match détermine le servlet sélectionné.
- si le dernier segment du chemin de L'URL contient une extension (par exemple .jsp), le container de servlet va essayer de correspondre à un servlet qui manipule les demandes de prolongation. Une extension est définie comme la partie de le dernier segment après le dernier".’ caractère.
- si aucune des trois règles précédentes n'aboutit à une correspondance de servlet, le conteneur tentera de servir un contenu approprié pour ressources demandées. Si un "défaut" servlet est défini pour le de l'application, il sera utilisé. De nombreux conteneurs fournissent une servlet par défaut pour servir le contenu.
le conteneur doit utiliser des comparaisons de chaînes de caractères sensibles à la casse pour l'appariement.
vous devriez également regarder la spécification des correspondances (donnée ci-dessous):
dans le descripteur de déploiement de L'application Web, la syntaxe suivante est utilisé pour définir mappings:
une chaîne commençant par un caractère
‘/’
et se terminant par un suffixe‘/*’
est utilisé pour la cartographie des chemins.une chaîne commençant par un préfixe
‘*.’
est utilisée comme mappage d'extension.la chaîne vide
("")
est un patron D'URL spécial qui correspond exactement à la racine du contexte de l'application, c'est à dire, les demandes de la formehttp://host:port/<contextroot>/
. Dans ce cas, l'information de chemin est’/’
et le chemin de servlet et le chemin de contexte sont des chaînes vides(““)
.une chaîne contenant seulement le caractère
’/’
indique le " défaut" servlet de l'application. Dans ce cas, le chemin de servlet est URI de la requête moins le chemin de contexte et les informations de chemin sont nulles.toutes autres les chaînes sont utilisées pour les correspondances exactes seulement
voyons maintenant des exemples. Considérons l'ensemble suivant de mappings:
Path Pattern Servlet /foo/bar/* servlet1 /baz/* servlet2 /catalog servlet3 *.bop servlet4
le comportement suivant résulterait:
Incoming Path Servlet Handling Request /foo/bar/index.html servlet1 /foo/bar/index.bop servlet1 /baz servlet2 /baz/index.html servlet2 /catalog servlet3 /catalog/index.html “default” servlet /catalog/racecar.bop servlet4 /index.bop servlet4
noter que dans le cas de /catalog/index.html
et /catalog/racecar.bop
, le
servlet mappée à “/catalog”
n'est pas utilisé parce que le match n'est pas exact.
maintenant à venir à votre problème :)
/path/test
fait partie du cinquième point de spécification des correspondances. Ce qui signifie que seuls les chemins se terminant par /path/test
cibleront servlet1
.
toutefois, /path/test/*
est admissible au premier point de la même spécification. Cela signifie que:
.../path/test
sera traité par servlet1
et
.../path/test/abc
sera traité par servlet2
qui a été vérifié par moi dans une application d'essai.
vos chemins sont en conflit.
les Deux chemins signifient la même chose, le '/*' ne fait aucune différence. Apparemment, lorsque vous essayez votre chemin, la dernière correspondance (servlet2) est exécutée.
vous mettez habituellement un chemin avec le nom de Servlet, comme par exemple:
/path/test/servlet1
/path/test/servlet2