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
Stringpattern matching limits what can be achieved. - Matching a
Stringpath to aStringpattern 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%2For%3Bwhich 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#urlDecodebut 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#removeSemicolonContentbut 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.jspbut alsocom/tast.jsporcom/txst.jspcom/*.jsp— matches all.jspfiles in thecomdirectorycom/**/test.jsp— matches alltest.jspfiles underneath thecompathorg/springframework/**/*.jsp— matches all.jspfiles underneath theorg/springframeworkpathorg/**/servlet/bla.jsp— matchesorg/springframework/servlet/bla.jspbut alsoorg/springframework/testing/servlet/bla.jspandorg/servlet/bla.jspcom/{filename:\\w+}.jspwill matchcom/test.jspand assign the valuetestto thefilenamevariable
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.htmlas well as/pages/tXst.htmlbut not/pages/toast.html/resources/*.png— matches all.pngfiles in theresourcesdirectory/resources/**— matches all files underneath the/resources/path, including/resources/image.pngand/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.pngwill match with "path" → "/image.png", and/resources/css/spring.csswill match with "path" → "/css/spring.css"/resources/{filename:\\w+}.datwill match/resources/spring.datand assign the value"spring"to thefilenamevariable
文章作者:Administrator
文章链接:http://localhost:8090//archives/pathpattern-antpathmatcher
版权声明:本博客所有文章除特别声明外,均采用CC BY-NC-SA 4.0 许可协议,转载请注明出处!
评论