|
|
|
@ -573,6 +573,56 @@ initialization parameters (`init-param` elements) to the Servlet declaration in |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[mvc-handlermapping-path]] |
|
|
|
|
|
|
|
=== Path Matching |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The Servlet API exposes the full request path as `requestURI` and further sub-divides it |
|
|
|
|
|
|
|
into `contextPath`, `servletPath`, and `pathInfo` whose values vary depending on how a |
|
|
|
|
|
|
|
Servlet is mapped. From these inputs, Spring MVC needs to determine the lookup path to |
|
|
|
|
|
|
|
use for handler mapping, which is the path within the mapping of the `DispatcherServlet` |
|
|
|
|
|
|
|
itself, excluding the `contextPath` and any `servletMapping` prefix, if present. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The `servletPath` and `pathInfo` are decoded and that makes them impossible to compare |
|
|
|
|
|
|
|
directly to the full `requestURI` in order to derive the lookupPath and that makes it |
|
|
|
|
|
|
|
necessary to decode the `requestUri`. However this introduces its own issues because the |
|
|
|
|
|
|
|
path may contain encoded reserved characters such as `"/"` or `";"` that can in turn |
|
|
|
|
|
|
|
alter the structure of the path after they are decoded which can also lead to security |
|
|
|
|
|
|
|
issues. In addition, Servlet containers may normalize the `servletPath` to varying |
|
|
|
|
|
|
|
degrees which makes it further impossible to perform `startsWith` comparisons against |
|
|
|
|
|
|
|
the `requestUri`. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
This is why it is best to avoid reliance on the `servletPath` which comes with the |
|
|
|
|
|
|
|
prefix-based `servletPath` mapping type. If the `DispatcherServlet` is mapped as the |
|
|
|
|
|
|
|
default Servlet with `"/"` or otherwise without a prefix with `"/*"` and the Servlet |
|
|
|
|
|
|
|
container is 4.0+ then Spring MVC is able to detect the Servlet mapping type and avoid |
|
|
|
|
|
|
|
use of the `servletPath` and `pathInfo` altogether. On a 3.1 Servlet container, |
|
|
|
|
|
|
|
assuming the same Servlet mapping types, the equivalent can be achieved by providing |
|
|
|
|
|
|
|
a `UrlPathHelper` with `alwaysUseFullPath=true` via <<mvc-config-path-matching>> in |
|
|
|
|
|
|
|
the MVC config. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fortunately the default Servlet mapping `"/"` is a good choice. However, there is still |
|
|
|
|
|
|
|
an issue in that the `requestUri` needs to be decoded to make it possible to compare to |
|
|
|
|
|
|
|
controller mappings. This is again undesirable because of the potential to decode |
|
|
|
|
|
|
|
reserved characters that alter the path structure. If such characters are not expected, |
|
|
|
|
|
|
|
then you can reject them (like the Spring Security HTTP firewall), or you can configure |
|
|
|
|
|
|
|
`UrlPathHelper` with `urlDecode=false` but controller mappings will need to match to the |
|
|
|
|
|
|
|
encoded path which may not always work well. Furthermore, sometimes the |
|
|
|
|
|
|
|
`DispatcherServlet` needs to share the URL space with another Servlet and may need to |
|
|
|
|
|
|
|
be mapped by prefix. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The above issues can be addressed more comprehensively by switching from `PathMatcher` to |
|
|
|
|
|
|
|
the parsed `PathPattern` available in 5.3 or higher, see |
|
|
|
|
|
|
|
<<mvc-ann-requestmapping-pattern-comparison>>. Unlike `AntPathMatcher` which needs |
|
|
|
|
|
|
|
either the lookup path decoded or the controller mapping encoded, a parsed `PathPattern` |
|
|
|
|
|
|
|
matches to a parsed representation of the path called `RequestPath`, one path segment |
|
|
|
|
|
|
|
at a time. This allows decoding and sanitizing path segment values individually without |
|
|
|
|
|
|
|
the risk of altering the structure of the path. Parsed `PathPattern` also supports |
|
|
|
|
|
|
|
the use of `servletPath` prefix mapping as long as the prefix is kept simple and does |
|
|
|
|
|
|
|
not have any characters that need to be encoded. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[mvc-handlermapping-interceptor]] |
|
|
|
[[mvc-handlermapping-interceptor]] |
|
|
|
=== Interception |
|
|
|
=== Interception |
|
|
|
|
|
|
|
|
|
|
|
@ -1650,7 +1700,7 @@ configuration. |
|
|
|
[.small]#<<web-reactive.adoc#webflux-ann-requestmapping-pattern-comparison, WebFlux>># |
|
|
|
[.small]#<<web-reactive.adoc#webflux-ann-requestmapping-pattern-comparison, WebFlux>># |
|
|
|
|
|
|
|
|
|
|
|
When multiple patterns match a URL, the best match must be selected. This is done with |
|
|
|
When multiple patterns match a URL, the best match must be selected. This is done with |
|
|
|
one of the following depending on whether parsed `PathPattern`'s are enabled for use or not: |
|
|
|
one of the following depending on whether use of parsed `PathPattern` is enabled for use or not: |
|
|
|
|
|
|
|
|
|
|
|
* {api-spring-framework}/web/util/pattern/PathPattern.html#SPECIFICITY_COMPARATOR[`PathPattern.SPECIFICITY_COMPARATOR`] |
|
|
|
* {api-spring-framework}/web/util/pattern/PathPattern.html#SPECIFICITY_COMPARATOR[`PathPattern.SPECIFICITY_COMPARATOR`] |
|
|
|
* {api-spring-framework}/util/AntPathMatcher.html#getPatternComparator-java.lang.String-[`AntPathMatcher.getPatternComparator(String path)`] |
|
|
|
* {api-spring-framework}/util/AntPathMatcher.html#getPatternComparator-java.lang.String-[`AntPathMatcher.getPatternComparator(String path)`] |
|
|
|
|