The MVC Java config and the MVC namespace now support options to
configure content negotiation. By default both support checking path
extensions first and the "Accept" header second. For path extensions
.json, .xml, .atom, and .rss are recognized out of the box if the
Jackson, JAXB2, or Rome libraries are available. The ServletContext
and the Java Activation Framework may be used as fallback options
for path extension lookups.
Issue: SPR-8420
After this change each call stack level pushes and pops an async
Callable to ensure the AsyncExecutionChain is in sync with the
call stack. Before this change, a controller returning a "forward:"
prefixed string caused the AsyncExecutionChain to contain a
extra Callables that did not match the actual call stack.
Issue: SPR-9611
Previously DefaultHandlerExceptionResolver did not handle BindException
but after this change it does. A BindException is raised when an
@ModelAttribute annotated argument is not followed by a BindingResult
argument. Hence this is unlikely to affect browser rendering.
For programmatic clients however this change ensures an unhandled
BindException is at least turned into a 400 error.
Issue: SPR-9310
The Atom/RSS message converters are now registered ahead of the
Jackson and the JAXB2 message converters by default. Since the Atom
and RSS converters convert to and from very specific object types
Feed and Channel respectively, that shouldn't introduce any regressions
and will work more intuitively when the requested media type is "*/*".
Issue: SPR-9054
Before this change @ExceptionHandler methods could be located in and
apply locally within a controller. The change makes it possible to have
such methods applicable globally regardless of the controller that
raised the exception.
The easiest way to do that is to add them to a class annotated with
`@ExceptionResolver`, a new annotation that is also an `@Component`
annotation (and therefore works with component scanning). It is also
possible to register classes containing `@ExceptionHandler` methods
directly with the ExceptionHandlerExceptionResolver.
When multiple `@ExceptionResolver` classes are detected, or registered
directly, the order in which they're used depends on the the `@Order`
annotation (if present) or on the value of the order field (if the
Ordered interface is implemented).
Issue: SPR-9112
Before this change the HandlerExecitionChain logged errors each time a
an AsyncHandlerInterceptor returned a null async Callable, a condition
which is acceptable.
SPR-9524
Return an empty map when there are no path variables, rather than
raising an exception. This is consistent with similar resolvers for
extracting headers and request parameters.
Issue: SPR-9289
Following the introduction of ContentNegotiationManager that allows,
among other things, to configure the file extensions to use for content
negotiation, this change adds "smart" suffix pattern match that matches
against the configured file extensions only rather than against any
extension.
Given the request mapping "/jobs/{jobName}" and one configured file
extension ("json"), a request for "/jobs/my.job" will select the
pattern "/jobs/{jobName}" while a request for "/jobs/my.job.json" will
select the pattern "/jobs/{jobName}.json". Previously, both requests
would have resulted in the pattern "/jobs/{jobName}.*".
Issue: SPR-7632, SPR-8474
The HTTP PATCH method is now supported whereever HTTP methods are used.
Annotated controllers can be mapped to RequestMethod.PATCH.
On the client side the RestTemplate execute(..) and exchange(..)
methods can be used with HttpMethod.PATCH. In terms of HTTP client
libraries, Apache HttpComponents HttpClient version 4.2 or later is
required (see HTTPCLIENT-1191). The JDK HttpURLConnection does not
support the HTTP PATCH method.
Issue: SPR-7985
Introduced ContentNeogtiationStrategy for resolving the requested
media types from an incoming request. The available implementations
are based on path extension, request parameter, 'Accept' header,
and a fixed default content type. The logic for these implementations
is based on equivalent options, previously available only in the
ContentNegotiatingViewResolver.
Also in this commit is ContentNegotiationManager, the central class to
use when configuring content negotiation options. It accepts one or
more ContentNeogtiationStrategy instances and delegates to them.
The ContentNeogiationManager can now be used to configure the
following classes:
- RequestMappingHandlerMappingm
- RequestMappingHandlerAdapter
- ExceptionHandlerExceptionResolver
- ContentNegotiatingViewResolver
Issue: SPR-8410, SPR-8417, SPR-8418,SPR-8416, SPR-8419,SPR-7722
Changes introduced in Spring 3.1 for Environment support inadvertently
established a cyclic dependency between the
org.springframework.web.context and
org.springframework.web.context.support packages, specifically through
web.context.ContextLoader's invocation of
web.context.support.WebApplicationContextUtils#initServletPropertySources.
This commit introduces ConfigurableWebEnvironment to break this cyclic
dependency. All web.context.ConfigurableWebApplicationContext types now
return web.context.ConfigurableWebEnvironment from their #getEnvironment
methods; web.context.support.StandardServletEnvironment now implements
ConfigurableWebEnvironment and makes the call to
web.context.support.WebApplicationContextUtils#initServletPropertySources
within its implementation of #initPropertySources. This means that
web.context.ContextLoader now invokes
web.context.ConfigurableWebEnvironment#initPropertySources instead of
web.context.support.WebApplicationContextUtils#initServletPropertySources
and thus the cycle is broken.
Issue: SPR-9439
Prior to this change, AbstractApplicationContext#setParent replaced the
child context's Environment with the parent's Environment if available.
This has the negative effect of potentially changing the type of the
child context's Environment, and in any case causes property sources
added directly against the child environment to be ignored. This
situation could easily occur if a WebApplicationContext child had a
non-web ApplicationContext set as its parent. In this case the parent
Environment type would (likely) be StandardEnvironment, while the child
Environment type would (likely) be StandardServletEnvironment. By
directly inheriting the parent environment, critical property sources
such as ServletContextPropertySource are lost entirely.
This commit introduces the concept of merging an environment through
the new ConfigurableEnvironment#merge method. Instead of replacing the
child's environment with the parent's,
AbstractApplicationContext#setParent now merges property sources as
well as active and default profile names from the parent into the
child. In this way, distinct environment objects are maintained with
specific types and property sources preserved. See #merge Javadoc for
additional details.
Issue: SPR-9444, SPR-9439
As of Spring 3.1 URI variables can be used for data binding purposes in
addition to request parameters (including query string and form params)
In some cases URI variables and request params can overlap (e.g. form
contains a child entity with an entityId as hidden form input while the
URI contains the entityId of the parent entity) and that can lead to
surprises if the application already exists.
This change ensures that request parameters are used first and URI
vars are added only if they don't overlap. Ideally however an
application should not use the same uri variable name as the name of
a request parameter where they don't refer to the same value.
Issue: SPR-9349
This commit introduces three abstract WebApplicationInitializers, to be
used in the typical setup of a Spring-based web application.
- AbstractContextLoaderInitializer provides an abstract base class for
registering a ContextLoaderListener.
- AbstractDispatcherServletInitializer provides an abstract base class
for registering a DispatcherServlet, with an optional root context.
- AbstractAnnotationConfigDispatcherServletInitializer provides an
abstract base class for registering a DispatcherServlet and optional
ContextLoaderListener based on annotated (e.g. @Configuration)
classes.
Issue: SPR-9300
Several test methods in RequestResponseBodyMethodProcessorTests
are currently annotated with @Test(expected=…) and additionally contain:
fail("Expected exception");
This combination is superfluous, and the unnecessary fail() invocations
have therefore been removed.
When URL decoding is turned off in AbstractHandlerMapping, the
extracted path variables are also not encoded. Turning off URL decoding
may be necessary for request mapping to work correctly when the path
may contain the (encoded) special character '/'. At the same time there
is no good reason not to leave path variables encoded. This change
ensures path variables are encoded when URL decoding is turned off.
Issue: SPR-9098
MappingJackson2JsonView and MappingJacksonJsonView now provide an
option that will set the Content-Length header of JSON responses.
Use of the option implies buffering of the response and it must be
enabled explicitly.
Issue: SPR-7866
This change makes it possible to provide a custom MessageCodesResolver
through the MVC Java config whether using @EnableWebMvc and extending
WebMVcConfigurerAdapter or sub-classing directly from
WebMvcConfigurationSupport.
Issue: SPR-9223
The new property can be used to ignore specific exceptions that may
otherwise be matched by the "exceptionMappings" property or resolved
through the defaultErrorView.
Issue: SPR-5193
When @ResponseStatus has a reason and servletResponse.sendError() is
called, the response is committed and should no longer be written to.
After this change, the ServletInvocableHandlerMethod will mark the
response fully handled and will ignore any non-null return values.
Issue: SPR-9159
Before this fix the q-value of media types in the Accept header were
ignored when using the new RequestMappingHandlerAdapter in combination
with @ResponseBody and HttpMessageConverters.
Issue: SPR-9160
Previously RequestMappingHandlerMapping detected @RequestMapping
methods through an initApplicationContext() hook. However, the
HandlerMapping may not have been fully set up with all its
dependencies at that point including settings like useSuffixPattern
and others.
This change moves the detection @RequestMapping methods to an
InitializingBean.afterPropertiesSet() hook.
Issue: SPR-9371
This was supported in DefaultAnnotationHandlerMapping but not in the
RequestMappingHandlerMapping. The specific scenario where this matters
is a controller decorated with a JDK proxy. In this scenario the
HandlerMapping looks at interfaces only to decide if the bean is a
controller. The @Controller annotation is better left (and required)
on the class.
Issue: SPR-9374
Jackson serialization supports pretty printing. Usually it's enabled
by invoking ObjectMapper.configure(..), which is not convenient for
apps with XML configuration. The Jackson HttpMessageConverter and View
now both have a prettyPrint property.
A second more serious issue is documented here:
https://github.com/FasterXML/jackson-databind/issues/12
The workaround discussed at the above link has been implemented.
Issue: SPR-7201
Jackson 2 uses completely new package names and new maven artifact ids.
This change adds Jackson 2 as an optional dependency and also provides
MappingJackson2HttpMessageConverter and MappingJackson2JsonView for use
with the new version.
The MVC namespace and the MVC Java config detect and use
MappingJackson2HttpMessageConverter if Jackson 2 is present.
Otherwise if Jackson 1.x is present,
then MappingJacksonHttpMessageConverter is used.
Issue: SPR-9302
This change updates Open-Session-in-View filters and interceptors for
use in async requests mainly ensuring the open Hibernate session is
unbound from the main request processing thread and bound to the to
async thread.
Issue: SPR-8517
Before this change there were numerous javadoc warnings being reported
while building Spring framework API.
This commit resolves most of the javadoc warnings, reducing the total
number from 265 to 103.
Issue: SPR-9113
* Clarify semantics and behavior of AsyncWebRequest methods in most cases
making a best effort and not raising an exception if async processing
has completed for example due to a timeout. The startAsync() method is
still protected with various checks and will raise ISE under a number
of conditions.
* Return 503 (service unavailable) when requests time out.
* Logging improvements.
Issue: SPR-8517
From a programming model perspective, @RequestMapping methods now
support two new return value types:
* java.util.concurrent.Callable - used by Spring MVC to obtain the
return value asynchronously in a separate thread managed transparently
by Spring MVC on behalf of the application.
* org.springframework.web.context.request.async.DeferredResult - used
by the application to produce the return value asynchronously in a
separate thread of its own choosing.
The high-level idea is that whatever value a controller normally
returns, it can now provide it asynchronously, through a Callable or
through a DeferredResult, with all remaining processing --
@ResponseBody, view resolution, etc, working just the same but
completed outside the main request thread.
From an SPI perspective, there are several new types:
* AsyncExecutionChain - the central class for managing async request
processing through a sequence of Callable instances each representing
work required to complete request processing asynchronously.
* AsyncWebRequest - provides methods for starting, completing, and
configuring async request processing.
* StandardServletAsyncWebRequest - Servlet 3 based implementation.
* AsyncExecutionChainRunnable - the Runnable used for async request
execution.
All spring-web and spring-webmvc Filter implementations have been
updated to participate in async request execution.
The open-session-in-view Filter and interceptors implementations in
spring-orm will be updated in a separate pull request.
Issue: SPR-8517
The new @MVC support classes select a HandlerMethodArgumentResolver
and a HandlerMethodReturnValueHandler statically, i.e. based on
the signature of the method, which means that a controller method
can't declare a more general return type like Object but actually
return a more specific one, e.g. String vs RedirectView, and
expect the right handler to be used.
The fix ensures that a HandlerMethodReturnValueHandler is selected
based on the actual return value type, which is something that was
supported with the old @MVC support classes. One consequence
of the change is the selected HandlerMethodReturnValueHandler can
no longer be cached but that matches the behavior of the old
@MVC support classes.
Issues: SPR-9218