パスマッチング
サーブレット API は、完全なリクエストパスを requestURI
として公開し、さらにそれを contextPath
、servletPath
、pathInfo
に細分します。contextPath
、servletPath
、pathInfo
の値は、サーブレットのマッピング方法によって異なります。これらの入力から、Spring MVC は、マッピングハンドラーに使用するルックアップパスを決定する必要があります。これにより、contextPath
および必要に応じて servletMapping
プレフィックスを除外する必要があります。
servletPath
と pathInfo
はデコードされているため、完全な requestURI
と直接比較して lookupPath を導出することは不可能であり、requestURI
をデコードする必要があります。ただし、パスには "/"
や ";"
などのエンコードされた予約文字が含まれる場合があり、デコード後にパスの構造が変更されてセキュリティ上の問題が発生する可能性があるため、これによって独自の問題が発生します。さらに、サーブレットコンテナーは servletPath
をさまざまな程度に正規化する可能性があり、これにより startsWith
を requestURI
と比較することがさらに不可能になります。
これが、プレフィックスベースの servletPath
マッピング型に付属する servletPath
への依存を避けることが最善の理由です。DispatcherServlet
が "/"
または "/*"
のプレフィックスなしでデフォルトのサーブレットとしてマップされ、サーブレットコンテナーが 4.0+ である場合、Spring MVC はサーブレットマッピング型を検出し、servletPath
と pathInfo
の使用を完全に回避できます。3.1 サーブレットコンテナーでは、同じサーブレットマッピング型を想定し、MVC 構成でパスマッチングを介して UrlPathHelper
と alwaysUseFullPath=true
を提供することで同等のことが実現できます。
幸い、デフォルトのサーブレットマッピング "/"
が適切な選択です。ただし、コントローラーのマッピングと比較できるようにするには、requestURI
をデコードする必要があるという課題があります。パス構造を変更する予約文字をデコードする可能性があるため、これも望ましくありません。そのような文字が予期されない場合は、拒否するか(Spring Security HTTP ファイアウォールなど)、urlDecode=false
を使用して UrlPathHelper
を構成できますが、コントローラーのマッピングはエンコードされたパスと一致する必要があります。さらに、DispatcherServlet
が URL スペースを別のサーブレットと共有する必要があり、プレフィックスでマッピングする必要がある場合があります。
上記の課題は、AntPathMatcher
との文字列パスマッチングの代わりに、PathPatternParser
と解析されたパターンを使用する場合に対処されます。PathPatternParser
は、バージョン 5.3 から Spring MVC で使用できるようになっており、バージョン 6.0 からデフォルトで有効になっています。デコードされたルックアップパスまたはエンコードされたコントローラーマッピングのいずれかを必要とする AntPathMatcher
とは異なり、解析された PathPattern
は、一度に 1 つのパスセグメントである RequestPath
と呼ばれるパスの解析された表現に一致します。これにより、パスの構造を変更するリスクなしに、パスセグメント値を個別にデコードおよびサニタイズできます。解析された PathPattern
は、サーブレットパスマッピングが使用され、プレフィックスが単純に保たれている、つまりエンコードされた文字がない限り、servletPath
プレフィックスマッピングの使用もサポートします。パターン構文の詳細と比較については、パターン比較を参照してください。