it-swarm.com.de

Kann jemand Servlet-Mapping erklären?

Ich versuche, eine Webanwendung mit SpringMVC zu schreiben. Normalerweise würde ich nur eine erfundene Dateierweiterung auf den Front-Controller von Spring abbilden und glücklich leben, aber dieses Mal werde ich REST-ähnliche URLs ohne Dateinamenerweiterungen verwenden.

Wenn ich alles unter meinem Kontextpfad dem Front-Controller zuordne (nennen wir es "app"), sollte ich mich auch um statische Dateien kümmern, etwas, das ich lieber nicht tun würde (warum noch ein neues Weel erfinden?) Daher scheint eine Kombination mit Tomcats Standardservlet (nennen wir es "Tomcat") der richtige Weg zu sein.

Ich habe das Ding dazu gebracht, so etwas zu tun

<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>

und das letztere für jede der Dateierweiterungen meines statischen Inhalts zu wiederholen. Ich frage mich nur, warum die folgenden Einstellungen, die für mich der obigen entsprechen, nicht funktionieren.

<!-- 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>

Kann jemand Licht ins Dunkel bringen?

51
agnul

Ich denke, ich kann wissen, was los ist.

In Ihrer aktiven Datei web.xml haben Sie Ihr Servlet als Standardservlet festgelegt (/ ist das Standardservlet, das aufgerufen wird, wenn keine anderen Übereinstimmungen vorliegen). Es beantwortet alle Anforderungen, die keiner anderen Zuordnung entsprechen.

In Fehler 1 scheint Ihre/* -Zuordnung eine gültige Pfadzuordnung zu sein. Mit der Zuordnung/* in web.xml werden alle Anforderungen mit Ausnahme anderer Pfadzuordnungen beantwortet. Erweiterungszuordnungen sind laut Spezifikation implizite Zuordnungen, die durch explizite Zuordnungen überschrieben werden. Aus diesem Grund ist die Erweiterungszuordnung fehlgeschlagen. Alles wurde explizit auf App abgebildet.

In Failed 2 ist die App für alles verantwortlich, mit Ausnahme des Inhalts, der der statischen Inhaltszuordnung entspricht. Um zu zeigen, was im Schnelltest passiert, habe ich eingerichtet. Hier ist ein Beispiel. /some-static-content-folder/ enthält test.png

Ich habe versucht, auf test.png zuzugreifen:

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

und die Datei wurde nicht gefunden. Wie auch immer versuchen

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

es kommt hoch. Es scheint also, dass das Tomcat-Standardservlet (mindestens 6.0.16) die Servlet-Zuordnung löscht und versucht, die Datei unter Verwendung des verbleibenden Pfads zu finden. Gemäß diesem Beitrag Servlet zum Bereitstellen statischer Inhalte zeigt Jetty das Verhalten, das Sie und ich erwartet hatten.

Gibt es einen Grund, warum Sie so etwas wie das Zuordnen eines Stammverzeichnisses für Ihre restlichen Anrufe nicht ausführen können? So etwas wie eine App, die/rest_root/* zugeordnet ist, als Sie für alles verantwortlich sind, was im Ordner rest_root vor sich geht, aber irgendwo anders sollte Tomcat damit umgehen, es sei denn, Sie nehmen eine andere explizite Zuordnung vor. Ich schlage vor, Ihr Rest-Servlet auf eine Pfadzuordnung zu setzen, da dies die Absicht besser erklärt. Die Verwendung von/oder/* erscheint nicht angemessen, da Sie die Ausnahmen festlegen müssen. Am Beispiel von SO, meine Restzuordnungen wären so ähnlich

/ users/* für das Benutzerservlet

/ posts/* für das Posts-Servlet

Zuordnungsreihenfolge

  1. Explizit (Pfadzuordnungen)
  2. Implizit (Erweiterungszuordnungen)
  3. Standard (/)

Bitte korrigieren Sie alles, was ich falsch verstanden habe.

43
Philip Tinney

Als Referenz ist der "fehlgeschlagene Versuch # 2" in der Version von Tomcat> = bis 6.0.29 vollkommen korrekt.

Es war das Ergebnis eines Tomcat-Fehlers, der in Version 6.0.29 behoben wurde:

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

Ich habe noch nie versucht, ein Servlet wie dieses zuzuordnen, aber ich würde behaupten, dass/* technisch gesehen mit/beginnt und mit/* endet, obwohl für beide Übereinstimmungen dasselbe Zeichen verwendet wird.

2
Adam Crume