サーブレットマッピングURLパターンの/と/ *の違い


175

おなじみのコード:

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

私の理解は、に/*マッピングされるということhttp://host:port/context/*です。

いかが/ですか?それは確かにhttp://host:port/contextルートのみにマップされません。実際、それは受け入れますhttp://host:port/context/helloが、拒否しhttp://host:port/context/hello.jspます。

誰がどのようにhttp://host:port/context/helloマッピングされるか説明できますか?

回答:


268

<url-pattern>/*</url-pattern>

/*サーブレットでは、デフォルトのサーブレットおよびJSP、サーブレットとしてservletcontainerによって提供されるすべてのサーブレットを含む他のすべてのサーブレットを、オーバーライド。起動する要求が何であれ、最終的にそのサーブレットになります。したがって、これはサーブレットにとって不適切なURLパターンです。通常は/*Filterオンリーワンで使いたいと思います。を呼び出すことで、より具体的なURLパターンをリッスンしているサーブレットのいずれかにリクエストを継続させることができますFilterChain#doFilter()

<url-pattern>/</url-pattern>

/他のサーブレットを上書きしません。他の登録済みサーブレットと一致しないすべてのリクエストに対して、サーブレットコンテナの組み込みのデフォルトサーブレットのみを置き換えます。これは通常、静的リソース(CSS / JS / image / etc)とディレクトリリストでのみ呼び出されます。servletcontainerの組み込みのデフォルトサーブレットは、HTTPキャッシュリクエスト、メディア(オーディオ/ビデオ)ストリーミング、ファイルダウンロードの再開にも対応できます。通常は、デフォルトのサーブレットをオーバーライドする必要はありません。そうしないと、すべてのタスクを処理する必要があるためです。これは簡単なことではありません(JSFユーティリティライブラリOmniFacesには、オープンソースの 例があります。)。したがって、これもサーブレットの悪いURLパターンです。JSPページがこのサーブレットにヒットしないのは、サーブレットコンテナの組み込みのJSPサーブレットが呼び出されるためです。これは、デフォルトで、より具体的なURLパターンにマッピングされています*.jsp

<url-pattern></url-pattern>

次に、空の文字列のURLパターンもあります 。これは、コンテキストルートが要求されたときに呼び出されます。これは<welcome-file>、サブフォルダーが要求されたときに呼び出されない方法とは異なります。これは、「ホームページサーブレット」が必要な場合に実際に探しているURLパターンである可能性が高いです。空の文字列のURLパターン とスラッシュのURLパターンを直感的に期待することを認めなければなりません/が逆に正確に定義されよいので、多くの初心者が混乱していることがわかります。しかし、それはそれが何であるかです。

フロントコントローラー

ケースでは、実際には、あなたのような、より具体的なURLパターンでそれを最高のマップのだ、フロントコントローラサーブレットを持っていき*.html*.do/pages/*/app/*あなたは一般的なURLパターンにフロントコントローラのURLパターンとカバーの静的リソースを離れて非表示にすることができます、などのような/resources/*/static/*サーブレットフィルターの助けを借りて。/ *にマップされているフロントコントローラサーブレットによって静的リソースが処理されないようにする方法も参照してください。Spring MVCには組み込みの静的リソースサーブレットがあることに注意してください。その/ため、Springで静的リソースの共通URLパターンを構成する場合、フロントコントローラーをマップできます。Spring MVCで静的コンテンツを処理する方法もご覧ください


9
ありがとう。少し調べてみて、微妙な点を明らかにしたい。/は、Webサーバーがインストールするデフォルトのサーブレットを上書きします。たとえば、Tomcatは静的リソースを提供するDefaultServletをインストールします。/を使用すると、デフォルトのサーブレットが(おそらく望ましくない)副作用として取り除かれます。
Candy Chiu

まあ、私はそれを「上書き」と呼ぶのではなく、「置換」と呼びます。このようにデフォルトのサーブレットを置き換えると便利です。
BalusC 2010年

1
<url-pattern> </ url-pattern>がエラーをスローします:サーブレットマッピングの<url-pattern>が無効です
スリム

エラーメッセージは、私のIDEではなくtomcatからのものでした。ただし、私はTomcat 6を使用しているので、おそらくそれが問題です;)
スリムな

2
@BalusC、どの/**パターンが示しているか教えていただけますか?
Sajib Acharya

45

BalusCの回答をマッピングルールと例で補足したいと思います。

サーブレット2.5仕様のマッピングルール:

  1. 正確なURLをマッピング
  2. ワイルドカードパスのマッピング
  3. マップ拡張
  4. デフォルトのサーブレットにマップする

この例では、3つのサーブレットがあります。/は、私たちがインストールするデフォルトのサーブレットです。Tomcatは、jspおよびjspxを提供する2つのサーブレットをインストールします。だから地図にhttp://host:port/context/hello

  1. 次に、正確なURLサーブレットがインストールされていません。
  2. 次に、ワイルドカードパスサーブレットがインストールされていません。
  3. 次の拡張子とは一致しません。
  4. デフォルトのサーブレットにマップして戻ります。

マップするには http://host:port/context/hello.jsp

  1. 次に、正確なURLサーブレットがインストールされていません。
  2. 次に、ワイルドカードパスサーブレットがインストールされていません。
  3. 拡張サーブレットが見つかり、戻ります。

25

おそらく私は404何時間も苦しんでいたので、URLがどのようにマッピングされているかも知っておく必要があります。リクエストを処理するハンドラーには2種類あります。BeanNameUrlHandlerMappingSimpleUrlHandlerMapping。を定義したときはservlet-mapping、を使用していSimpleUrlHandlerMappingます。知っておくべきことの1つは、これら2つのハンドラーが、alwaysUseFullPathデフォルトでと呼ばれる共通のプロパティを共有することfalseです。

falseここで、Springは完全パスを使用してURLをコントローラーにマップしないことを意味します。どういう意味ですか?これは、以下を定義するときを意味しますservlet-mapping

<servlet-mapping>
    <servlet-name>viewServlet</servlet-name>
    <url-pattern>/perfix/*</url-pattern>
</servlet-mapping>

ハンドラーは実際に*パーツを使用してコントローラーを見つけます。たとえば、次のコントローラを404使用してリクエストすると、エラーが発生します/perfix/api/feature/doSomething

@Controller()
@RequestMapping("/perfix/api/feature")
public class MyController {
    @RequestMapping(value = "/doSomething", method = RequestMethod.GET) 
    @ResponseBody
    public String doSomething(HttpServletRequest request) {
        ....
    }
}

パーフェクトマッチですね。しかし、なぜか404。前述のように、デフォルト値のalwaysUseFullPathfalseはfalseです。つまり、リクエストで/api/feature/doSomethingは、対応するコントローラーを見つけるためにのみ使用されますが、コントローラーはそのパスを気にしません。URLをMyController baseに変更するか、MyController baseから/perfix/perfix/api/feature/doSomething削除する必要があります。perfix@RequestingMapping


8

キャンディの答えはほとんど正しいと思います。そうでないと私が思う小さな部分が1つあります。

host:port / context / hello.jspをマップするには

  1. 次に、正確なURLサーブレットがインストールされていません。
  2. ワイルドカードパスサーブレットが見つかりました

「/ *」が「/ hello」をファイルではなくパスとして扱うため(拡張子がないため)、「/ *」がhost:port / context / helloと一致しないのはなぜかと思います。


2

との本質的な違いは/*/マッピングのある/*サーブレットは、拡張マッピングの*.htmlあるサーブレット(など)の前に選択されますが、マッピングのあるサーブレットは/、拡張マッピングが考慮された後にのみ選択されます(それ以外のリクエストには使用されます)他のものと一致します---「デフォルトサーブレット」です)。

特に、/*マッピングは/マッピングの前に常に選択されます。どちらかを指定すると、リクエストがコンテナ自体のデフォルトサーブレットに到達するのを防ぎます。

どちらかだけで完全に一致(のようなあるサーブレットマッピング後に選択されます/foo/bar)とより長いパスマッピングされているもの/*(のように/foo/*)。空の文字列マッピングは、コンテキストルート(http://host:port/context/)と完全に一致することに注意してください。

バージョン3.1のhttp://download.oracle.com/otndocs/jcp/servlet-3_1-fr-eval-spec/index.htmlにあるJavaサーブレット仕様の第12章を参照してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.