路径匹配
Servlet API 将完整的请求路径公开为requestURI
并进一步细分
到contextPath
,servletPath
和pathInfo
其值根据
Servlet 已映射。从这些输入中, Spring MVC 需要确定到
用于映射处理程序,它应该排除contextPath
和任何servletMapping
前缀(如果适用)。
这servletPath
和pathInfo
被解码,这使得它们无法比较
直接完整requestURI
为了派生 lookupPath,这使得它
解码requestURI
.但是,这引入了它自己的问题,因为
path 可能包含编码的保留字符,例如 或
在解码后更改路径的结构,这也可能导致安全性
问题。此外,Servlet 容器可以将"/"
";"
servletPath
到变化
度,这使得它进一步无法执行startsWith
比较
这requestURI
.
这就是为什么最好避免依赖servletPath
它附带了
基于前缀servletPath
mapping 类型。如果DispatcherServlet
映射为
default Servlet 带有或不带有前缀 with,并且 Servlet
container 为 4.0+,则 Spring MVC 能够检测 Servlet 映射类型并避免
使用"/"
"/*"
servletPath
和pathInfo
完全。在 3.1 Servlet 容器上,
假设相同的 Servlet 映射类型,则可以通过提供
一个UrlPathHelper
跟alwaysUseFullPath=true
通过 路径匹配
MVC 配置。
幸运的是,默认的 Servlet 映射是一个不错的选择。然而,仍然有
一个问题,因为"/"
requestURI
需要解码以使其能够与
controller 映射。这同样是不可取的,因为有可能解码
更改路径结构的保留字符。如果不需要此类字符,
然后你可以拒绝它们(如 Spring Security HTTP 防火墙),或者你可以配置UrlPathHelper
跟urlDecode=false
但是控制器映射需要与
编码路径,这可能并不总是正常工作。此外,有时DispatcherServlet
需要与另一个 Servlet 共享 URL 空间,并且可能需要
由 prefix 映射。
上述问题已在使用PathPatternParser
和解析的模式,如
String 路径匹配的替代方法AntPathMatcher
.这PathPatternParser
具有
从 5.3 版开始即可在 Spring MVC 中使用,并且默认从
版本 6.0。与AntPathMatcher
它需要解码的查找路径或
controller mapping encoded,解析的PathPattern
匹配到已解析的表示
的路径RequestPath
,一次一个路径段。这允许解码和
单独清理 path segment 值,而不会改变结构
路径。解析PathPattern
还支持使用servletPath
前缀映射
只要使用 Servlet 路径映射并且前缀保持简单,即它没有
编码字符。有关模式语法的详细信息和比较,请参阅模式比较。