The Spring documentation
(http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/mvc.html#mvc-ann-requestmapping)
describes in detail the request matching features provided by @RequestMapping
. An
important, if not the most important request matching criterion, is matching the request URI
path against the URI templates defined by @RequestMapping
annotations, a process
performed by a PathMatcher
implementation. There are two differences between
Spring's default AntPathMatcher
implementation and the
UriTemplatePathMatcher
provided by the CAE:
@RequestMapping
supports the use of regular expressions in URI template variables, specified as{variable:regex}
. An URL path will only be considered a match, if all the extracted URI template variable values match the corresponding regular expressions. If no regular expression is specified for a variable, the default is"[^/]+?"
, that is, any non-empty sequence of any characters except a slash'/'
. In other words, by default, a variable can match only one non-empty URI path segment. For instance, the URI template/{segment}
would match the URI path/home
, but not/news/breaking
.If the regular expression allows for a slash character
'/'
, the CAE path matcher implementation can match multiple path segments for a single variable. This would not be possible with Spring's default path matcher. For instance, the URI template/{segments:.+}/index.html
would match the URI path/one/two/index.html
, with variablesegment
bound to"one/two"
. As a convenience and to simplify handler method implementations, an@PathVariable
handler method argument representing a template variable can be of typeList<String>
. In this case, the variable value will be split into a list of path segments separated by slash characters'/'
. In the previous example, the list["one", "two"]
would be passed to the handler method.UriTemplatePathMatcher
does not support Ant-style globs:*
,**
, and?
. These characters should not be used in the literal part of URI templates, but only in regular expressions associated with template variables. Outside a template variable definition, they will be interpreted literally.
URI path matching behavior is not only influenced by @RequestMapping
annotations,
but also by some global Spring configuration parameters:
RequestMappingHandlerMapping.useTrailingSlashMatch
istrue
by default and causes any URI path with a trailing slash to be a match for a given URI template, if the template does not end with a slash, and the URI path without the slash would be a match. In effect, URIs will typically match a template, if they have a trailing slash, even if the template does not have a trailing slash. For instance, the URI template/{segment}
will match both/home
and/home/
.RequestMappingHandlerMapping.useSuffixPatternMatch
istrue
by default and causes any URI path with an extra.*
suffix (dot, plus some characters) to match a template, if the template does not contain any'.'
characters. In effect, the URI path matching process will typically ignore extra path suffixes, if the template does not contain any dot characters. For instance, the URI template/{segment}/index
will match both/home/index
and/home/index.html
.UrlPathHelper.urlDecode
istrue
by default and causes request URI paths to be percent decoded according to RFC 3986, before they are matched against any URI template. This is usually the desired behavior and should not be changed as it relieves the application developer from taking into consideration percent encoding when defining URI templates. Any template variable regular expressions should therefore match the decoded form of reserved characters, if such characters are to be allowed in variable values. For instance, the URI template/products/{name:[a-zäöü]+}
will match the request URI path/products/m%C3%A4use
(assuming a request character encoding of UTF-8, see below). Note that the percent character'%'
is not a valid name character as defined by the URI template. The matching process operates on the decoded URI path/products/mäuse
.As a consequence of this behavior, an application cannot differentiate during matching, whether the client sent a character percent encoded or not. Due to this ambiguity, an application should not generate URLs with path segments containing (percent encoded) slash characters
'/'
. Even though such URLs are valid and can be generated, the matching process acting on the decoded path would treat such path segment as multiple segments. URLs with path segments containing encoded slash characters are considered unsound and should be avoided. Given the same example URI template as above, if the link scheme expanded the URI template with aname
value of"tablets/laptops"
, this would result in the valid URI path/products/tablets%2Flaptops
. However, when dispatching a request for this path, it would be decoded and matched against URI templates as/products/tablets/laptops
, and the template/products/{name:[a-zäöü]+}
would not match.When percent decoding the request URI path,
UrlPathHelper
uses the request encoding (HttpServletRequest#getCharacterEncoding
) or defaults to ISO-8859-1, if no request character encoding is available. Since this default character encoding is different from theUriComponents
default encoding (UTF-8) during URL generation, it is recommended to force there request character encoding to UTF-8 by configuring anorg.springframework.web.filter.CharacterEncodingFilter
in the application'sweb.xml
, withencoding=UTF-8
andforceEncoding=true
:<filter> <filter-name>Character Encoding Filter</filter-name> <filter-class> org.springframework.web.filter.CharacterEncodingFilter </filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter>