Url matching PathPattern & AntPathMatcher

May 23, 2025 / Administrator / 0阅读 / 0评论/ 分类: SpringBoot3

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:

  1. 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.
  2. Matching a String path to a String 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 via UrlPathHelper#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.
  3. 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 with UrlPathHelper#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:

  1. 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.
  2. 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 — matches com/test.jsp but also com/tast.jsp or com/txst.jsp
  • com/*.jsp — matches all .jsp files in the com directory
  • com/**/test.jsp — matches all test.jsp files underneath the com path
  • org/springframework/**/*.jsp — matches all .jsp files underneath the org/springframework path
  • org/**/servlet/bla.jsp — matches org/springframework/servlet/bla.jsp but also org/springframework/testing/servlet/bla.jsp and org/servlet/bla.jsp
  • com/{filename:\\w+}.jsp will match com/test.jsp and assign the value test to the filename 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 the resources 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 the filename variable

文章作者:Administrator

文章链接:http://localhost:8090//archives/pathpattern-antpathmatcher

版权声明:本博客所有文章除特别声明外,均采用CC BY-NC-SA 4.0 许可协议,转载请注明出处!


评论