Url matching PathPattern & AntPathMatcher
path & pattern
这里有2个概念: path 和 pattern
path指的就是,我们动态传入的路径
而pattern指的是,我们给定的匹配规则
Why prefer pathPattern instead of AntPathMatcher
AntPathMatcher
In Spring applications AntPathMatcher
is used to identify classpath, file system, remote, and other resources in Spring configuration. It has also been used in Spring MVC to match URL paths. Over time the use of patterns in web applications grew in number and syntax with AntPathMatcher
evolving to meet those needs but some pain points remain without a solution:
- In web applications, patterns need to be matched many times per request and therefore any gains in performance and efficiency matter. However
String
pattern matching limits what can be achieved. - Matching a
String
path to aString
pattern makes it difficult to avoid URI encoding issues. For example should the incoming path be decoded first and then matched? That allows for patterns themselves to be declared without encoded characters, but what if the request path contains%2F
or%3B
which are/
and;
respectively? Once decoded those alter the structure of the path making it harder to match reliably. We could leave the request path encoded viaUrlPathHelper#urlDecode
but then we can't use a prefix Servlet mapping because the servletPath itself is decoded, and our patterns would need to be encoded too. - Path parameters presents a similar challenge. They can be removed before matching but what if we want to extract them via
@MatrixVariable
? We can leave them in the path withUrlPathHelper#removeSemicolonContent
but now patterns must take into account path parameters.
URL Matching with PathPattern
Patterns are parsed on startup and re-used at runtime for efficient URL matching. How much more efficient? It's hard to give numbers without a concrete use case but our jmh benchmark shows 6-8 times the throughput and 30-40% reduction in allocation rate. You can tailor the benchmark to get numbers that are more accurate for your application.
PathPattern
is compatible with AntPathMatcher
syntax except for the following:
- Support for additional syntax to match and capture 0 or more path segments at the end, e.g.
"/foo/{*spring}"
. This is useful as a catch-all pattern in REST APIs with access to the captured path segments through a@PathVariable
. - Support for
"**"
for multi-segment matching is only allowed at the end of a pattern. This helps to eliminate most causes of ambiguity when choosing the closest match for a given request.
PathContainer
helps to address the remaining issues. For example it never decodes the full path but rather breaks it down and decodes path segments individually, also removing path parameters, with the resulting decoded and normalized values matched one at a time. Therefore encoded "/"
and ";"
cannot alter the structure of the path, and path parameters can still be kept available. That means there is no need to configure how the request path is parsed and there are no trade-offs to consider.
the pattern syntax
the syntax for AntPathMatcher
https://docs.spring.vmware.com/spring-framework/docs/6.0.24/javadoc-api/org/springframework/util/AntPathMatcher.html
PathMatcher
implementation for Ant-style path patterns.Part of this mapping code has been kindly borrowed from Apache Ant.
The mapping matches URLs using the following rules:
?
matches one character*
matches zero or more characters**
matches zero or more directories in a path{spring:[a-z]+}
matches the regexp[a-z]+
as a path variable named "spring"
Examples
com/t?st.jsp
— matchescom/test.jsp
but alsocom/tast.jsp
orcom/txst.jsp
com/*.jsp
— matches all.jsp
files in thecom
directorycom/**/test.jsp
— matches alltest.jsp
files underneath thecom
pathorg/springframework/**/*.jsp
— matches all.jsp
files underneath theorg/springframework
pathorg/**/servlet/bla.jsp
— matchesorg/springframework/servlet/bla.jsp
but alsoorg/springframework/testing/servlet/bla.jsp
andorg/servlet/bla.jsp
com/{filename:\\w+}.jsp
will matchcom/test.jsp
and assign the valuetest
to thefilename
variable
Note: a pattern and a path must both be absolute or must both be relative in order for the two to match. Therefore, it is recommended that users of this implementation to sanitize patterns in order to prefix them with "/" as it makes sense in the context in which they're used.
the syntax for path pattern
https://docs.spring.vmware.com/spring-framework/docs/6.0.24/javadoc-api/org/springframework/web/util/pattern/PathPattern.html
Representation of a parsed path pattern. Includes a chain of path elements for fast matching and accumulates computed state for quick comparison of patterns.PathPattern
matches URL paths using the following rules:
?
matches one character*
matches zero or more characters within a path segment**
matches zero or more path segments until the end of the path{spring}
matches a path segment and captures it as a variable named "spring"{spring:[a-z]+}
matches the regexp[a-z]+
as a path variable named "spring"{*spring}
matches zero or more path segments until the end of the path and captures it as a variable named "spring"
Note: In contrast to AntPathMatcher
, **
is supported only at the end of a pattern. For example /pages/{**}
is valid but /pages/{**}/details
is not. The same applies also to the capturing variant {*spring}
. The aim is to eliminate ambiguity when comparing patterns for specificity.
Examples
/pages/t?st.html
— matches/pages/test.html
as well as/pages/tXst.html
but not/pages/toast.html
/resources/*.png
— matches all.png
files in theresources
directory/resources/**
— matches all files underneath the/resources/
path, including/resources/image.png
and/resources/css/spring.css
/resources/{*path}
— matches all files underneath the/resources/
, as well as/resources
, and captures their relative path in a variable named "path";/resources/image.png
will match with "path" → "/image.png", and/resources/css/spring.css
will match with "path" → "/css/spring.css"/resources/{filename:\\w+}.dat
will match/resources/spring.dat
and assign the value"spring"
to thefilename
variable
文章作者:Administrator
文章链接:http://localhost:8090//archives/pathpattern-antpathmatcher
版权声明:本博客所有文章除特别声明外,均采用CC BY-NC-SA 4.0 许可协议,转载请注明出处!
评论