Disable suffix pattern matching in Spring MVC

This commit disables by default suffix pattern matching in Spring MVC
applications. As described in the Spring MVC documentation (see
https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-ann-requestmapping-suffix-pattern-match),
this is considered as best practice.

This change also introduces new configuration properties to achieve
similar results in a safer way (using query parameters) or to rollback
to the former default.

Closes gh-11105
This commit is contained in:
Brian Clozel
2018-01-15 11:10:05 +01:00
parent 2bf662f231
commit 67e5897c40
5 changed files with 227 additions and 10 deletions

View File

@@ -393,6 +393,9 @@ content into your application. Rather, pick only the properties that you need.
# SPRING MVC ({sc-spring-boot-autoconfigure}/web/servlet/WebMvcProperties.{sc-ext}[WebMvcProperties])
spring.mvc.async.request-timeout= # Amount of time before asynchronous request handling times out.
spring.mvc.content-negotiation.favor-path-extension=false # Whether the path extension in the URL path should be used to determine the requested media type.
spring.mvc.content-negotiation.favor-parameter=false # Whether a request parameter ("format" by default) should be used to determine the requested media type.
spring.mvc.content-negotiation.parameter-name= # Query parameter name to use when "favor-parameter" is enabled.
spring.mvc.date-format= # Date format to use. For instance, `dd/MM/yyyy`.
spring.mvc.dispatch-trace-request=false # Whether to dispatch TRACE requests to the FrameworkServlet doService method.
spring.mvc.dispatch-options-request=true # Whether to dispatch OPTIONS requests to the FrameworkServlet doService method.
@@ -404,6 +407,8 @@ content into your application. Rather, pick only the properties that you need.
spring.mvc.log-resolved-exception=false # Whether to enable warn logging of exceptions resolved by a "HandlerExceptionResolver".
spring.mvc.media-types.*= # Maps file extensions to media types for content negotiation.
spring.mvc.message-codes-resolver-format= # Formatting strategy for message codes. For instance, `PREFIX_ERROR_CODE`.
spring.mvc.path-match.use-registered-suffix-pattern=false # Whether suffix pattern matching should work only against path extensions explicitly registered with "spring.mvc.media-types.*".
spring.mvc.path-match.use-suffix-pattern=false # Whether to use suffix pattern match (".*") when matching patterns to requests.
spring.mvc.servlet.load-on-startup=-1 # Load on startup priority of the Spring Web Services servlet.
spring.mvc.static-path-pattern=/** # Path pattern used for static resources.
spring.mvc.throw-exception-if-no-handler-found=false # Whether a "NoHandlerFoundException" should be thrown if no Handler was found to process a request.

View File

@@ -2053,6 +2053,52 @@ root of the classpath (in that order). If such a file is present, it is automati
used as the favicon of the application.
[[boot-features-spring-mvc-pathmatch]]
==== Path Patching and Content Negotiation
Spring MVC can map incoming HTTP requests to handlers by looking at the request path and
matching it to the mappings defined in your application (for example, `@GetMapping`
annotations on Controller methods).
Spring Boot chooses to disable suffix pattern matching by default, which means that
requests like `"GET /projects/spring-boot.json"` won't be matched to
`@GetMapping("/project/spring-boot")` mappings.
This is considered as a
{spring-reference}web.html#mvc-ann-requestmapping-suffix-pattern-match[best practice
for Spring MVC applications]. This feature was mainly useful in the past for HTTP
clients which did not send proper "Accept" request headers; we needed to make sure
to send the correct Content Type to the client. Nowadays, Content Negotiation
is much more reliable.
There are other ways to deal with HTTP clients that don't consistently send proper
"Accept" request headers. Instead of using suffix matching, we can use a query
parameter to ensure that requests like `"GET /projects/spring-boot?format=json"`
will be mapped to `@GetMapping("/project/spring-boot")`:
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
----
spring.mvc.content-negotiation.favor-parameter=true
# We can change the parameter name, which is "format" by default:
# spring.mvc.content-negotiation.parameter-name=myparam
# We can also register additional file extensions/media types with:
spring.mvc.media-types.markdown=text/markdown
----
If you understand the caveats and would still like your application to use
suffix pattern matching, the following configuration is required:
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
----
spring.mvc.content-negotiation.favor-path-extension=true
# You can also restrict that feature to known extensions only
# spring.mvc.path-match.use-registered-suffix-pattern=true
# We can also register additional file extensions/media types with:
# spring.mvc.media-types.adoc=text/asciidoc
----
[[boot-features-spring-mvc-web-binding-initializer]]
==== ConfigurableWebBindingInitializer