web-dev-qa-db-fra.com

Quelqu'un peut-il expliquer le mappage des servlets?

J'essaie d'écrire une application Web à l'aide de SpringMVC. Normalement, je mappais simplement une extension de fichier inventée sur le contrôleur frontal de Spring et vivais heureux, mais cette fois, je vais pour des URL de type REST, sans extension de nom de fichier.

Tout mapper sous mon chemin de contexte vers le contrôleur frontal (appelons-le "app") signifie que je devrais également prendre soin des fichiers statiques, ce que je préfère ne pas faire (pourquoi réinventer encore un autre weel?) , donc une combinaison avec le servlet par défaut de Tomcat (appelons-le "Tomcat") semble être la voie à suivre.

J'ai réussi à faire quelque chose comme

<servlet-mapping>
  <servlet-name>app</servlet-name>
  <url-pattern>/</url-pattern>
</servlet-mapping>

<servlet-mapping>
  <servlet-name>Tomcat</servlet-name>
  <url-pattern>*.ext</url-pattern>
</servlet-mapping>

et en répétant cette dernière pour chacune des extensions de fichier de mon contenu statique. Je me demande simplement pourquoi les configurations suivantes, qui pour moi sont équivalentes à celle ci-dessus, ne fonctionnent pas.

<!-- failed attempt #1 -->
<servlet-mapping>
  <servlet-name>app</servlet-name>
  <url-pattern>/*</url-pattern>
</servlet-mapping>

<servlet-mapping>
  <servlet-name>Tomcat</servlet-name>
  <url-pattern>*.ext</url-pattern>
</servlet-mapping>

<!-- failed attempt #2 -->
<servlet-mapping>
  <servlet-name>app</servlet-name>
  <url-pattern>/</url-pattern>
</servlet-mapping>

<servlet-mapping>
  <servlet-name>Tomcat</servlet-name>
  <url-pattern>/some-static-content-folder/*</url-pattern>
</servlet-mapping>

Quelqu'un peut-il nous éclairer?

51
agnul

Je pense que je sais peut-être ce qui se passe.

Dans votre web.xml de travail, vous avez défini votre servlet comme servlet par défaut (/ en soi est le servlet par défaut appelé s'il n'y a pas d'autres correspondances), il répondra à toute demande qui ne correspond pas à un autre mappage.

Dans Échec 1, votre mappage/* semble être un mappage de chemin valide. Avec le mappage/* dans web.xml, il répond à toutes les demandes, à l'exception des autres mappages de chemins. Selon la spécification, les mappages d'extension sont des mappages implicites qui sont remplacés par des mappages explicites. C'est pourquoi le mappage d'extension a échoué. Tout a été explicitement mappé à l'application.

Dans Failed 2, App est responsable de tout, à l'exception du contenu qui correspond au mappage de contenu statique. Pour montrer ce qui se passe dans le test rapide que j'ai mis en place. Voici un exemple. /some-static-content-folder/ contient test.png

Essayer d'accéder à test.png J'ai essayé:

/some-static-content-folder/test.png

et le fichier est introuvable. Cependant essayer

/some-static-content-folder/some-static-content-folder/test.png

ça monte. Il semble donc que le servlet par défaut de Tomcat (6.0.16 au moins) supprime le mappage de servlet et essaiera de trouver le fichier en utilisant le chemin restant. Selon cet article Servlet pour servir du contenu statique Jetty donne le comportement que vous et moi attendions.

Y a-t-il une raison pour laquelle vous ne pouvez pas faire quelque chose comme mapper un répertoire racine pour vos appels de repos. Quelque chose comme l'application mappée sur/rest_root/* que vous êtes responsable de tout ce qui se passe dans le dossier rest_root, mais n'importe où ailleurs devrait être géré par Tomcat, à moins que vous ne fassiez un autre mappage explicite. Je suggère de définir votre servlet de repos sur un mappage de chemin, car il déclare mieux l'intention. L'utilisation de/ou/* ne semble pas appropriée, car vous devez tracer les exceptions. En utilisant SO comme exemple, mes mappages de repos seraient quelque chose comme

/ users/* pour le servlet utilisateur

/ posts/* pour le servlet posts

Ordre de mappage

  1. Explicite (mappages de chemins)
  2. Implicite (mappages d'extension)
  3. Défaut (/)

Veuillez corriger tout ce que je me suis trompé.

43
Philip Tinney

Pour référence, la "tentative échouée # 2" est parfaitement correcte dans la version de Tomcat> = à 6.0.29.

C'était le résultat d'un bogue Tomcat qui a été corrigé dans la version 6.0.29:

https://issues.Apache.org/bugzilla/show_bug.cgi?id=50026

<!-- Correct for Tomcat >= 6.0.29 or other Servlet containers -->
<servlet-mapping>
  <servlet-name>app</servlet-name>
  <url-pattern>/</url-pattern>
</servlet-mapping>

<servlet-mapping>
  <servlet-name>default</servlet-name>
  <url-pattern>/some-static-content-folder/*</url-pattern>
</servlet-mapping>
3
PragmaCoder

Je n'ai jamais essayé de mapper une servlet comme celle-ci, mais je dirais soutiens que/* commence techniquement par/et se termine par/*, même si le même caractère est utilisé pour les deux correspondances.

2
Adam Crume