web-dev-qa-db-ja.com

誰でもサーブレットマッピングを説明できますか?

SpringMVCを使用してWebアプリケーションを作成しようとしています。通常、作成したファイル拡張子をSpringのフロントコントローラーにマップし、うまくいきますが、今回はファイル名拡張子のないRESTのようなURLを使用します。

コンテキストパスの下にあるすべてをフロントコントローラーにマッピングします( "app"と呼びましょう)は、静的ファイルも処理する必要があることを意味します(やめたいのはなぜですか?) 、Tomcatのデフォルトサーブレットとの組み合わせ(「Tomcat」と呼びましょう)が道のりのようです。

私は次のようなことをして仕事をしました

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

誰もが光を当てることができますか?

51
agnul

私は何が起こっているか知っていると思う。

作業web.xmlで、サーブレットをデフォルトサーブレットに設定しました(/自体は、他に一致するものがない場合に呼び出されるデフォルトサーブレットです)。別のマッピングに一致しない要求に応答します。

Failed 1では、/ *マッピングは有効なパスマッピングのように見えます。 web.xmlの/ *マッピングを使用すると、他のパスマッピングを除くすべての要求に応答します。仕様によると、拡張マッピングは、明示的なマッピングによって上書きされる暗黙的なマッピングです。それが拡張マッピングが失敗した理由です。すべてが明示的にアプリにマッピングされました。

失敗2では、静的コンテンツマッピングに一致するコンテンツを除き、アプリがすべてを担当します。私が設定したクイックテストで何が起こっているかを示すために。以下に例を示します。 /some-static-content-folder/にはtest.pngが含まれます

Test.pngにアクセスしようとしました:

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

ファイルが見つかりませんでした。しかししようとしている

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

出てきます。そのため、Tomcatのデフォルトサーブレット(少なくとも6.0.16)はサーブレットマッピングを削除し、残りのパスを使用してファイルを見つけようとします。この投稿によると、 静的コンテンツを提供するサーブレット Jettyは、あなたと私が期待していた動作を提供します。

残りの呼び出しのルートディレクトリをマップするようなことができない理由はありますか。/rest_root/*にマップされたappのようなものは、rest_rootフォルダー内で行われるすべての処理を担当しますが、別の明示的なマッピングを行わない限り、Tomcatによって処理される必要があります。目的をより適切に宣言するため、残りのサーブレットをパスマッピングに設定することをお勧めします。 /または/ *を使用するのは適切ではないようです。例外をマップする必要があるからです。例としてSOを使用すると、残りのマッピングは次のようになります

ユーザーサーブレットの/ users/*

/ posts/*投稿サーブレット用

マッピング順序

  1. 明示的(パスマッピング)
  2. 暗黙的(拡張マッピング)
  3. デフォルト (/)

私が間違ったことを修正してください。

43
Philip Tinney

参考までに、「失敗した試行#2」は、Tomcatのバージョン6.0.29以降では完全に正しいです。

これは、バージョン6.0.29で修正されたTomcatバグの結果です。

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

このようなサーブレットをマッピングしようとしたことはありませんが、wouldは、両方の一致に同じ文字が使用されていても、/ *は技術的には/で始まり、/ *で終わると主張します。

2
Adam Crume