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 HandlerMethod used ClassUtils.getUserClass(Class<?>)
to get the real user class, and not one generated by CGlib. However it
failed to that under all circumstances. This change fixes that.
Issue: SPR-9490
Before this change the StringHttpMessageConverter used a fixed charset
"ISO-8859-1" if the requested content type did not specify one. This
change adds a defaultCharset field and a constructor to configure it in
StringHttpMessageConverter.
Issue: SPR-9487
Ensure that NonClosingOutputStream calls with a byte array call the
corresponding methods of the underlying OutputStream rather than
relying on the default NonClosingOutputStream implementation, which
writes one bte at a time. This significantly improves performance.
Issues: SPR-9530
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
Commit aa415d7c0c introduced
JacksonObjectMapperFactoryBean and associated tests, but with Windows
(CRLF) line endings instead of the conventional Unix (LF) line endings.
This commit converts these files to LF endings using the handy
`dos2unix` utility.
Issue: SPR-9125
The BeanFactory makes it easier to configure a customized Jackson
ObjectMapper (for example enable/disable certain features).
This bean factory is usually used with
MappingJacksonHttpMessageConverter or MappingJacksonJsonView.
See JavaDoc for examples.
Issue: SPR-9125
Previously MediaType could only parse double-quoted parameters without
raising an IllegalArgumentException. Now parameters can also be
single-quoted.
Issue: SPR-8917
HttpStatus cannot be created with an unknown status code. If a server
returns a status code that's not in the HttpStatus enum values, an
IllegalArgumentException is raised. Rather than allowing it to
propagate as such, this change ensures the actual exception raised is
a RestClientException.
Issue: SPR-9406
Default HTTP error exceptions thrown from RestTemplate now include
response headers in addition to the response body. In particular, this
enables inspection of the Content-Type header allowing manual
deserialization of the response body without guessing as to the content
type.
- introduce HttpStatusCodeException#getResponseHeaders
- add constructor with headers param for HttpStatusCodeException,
HttpClientErrorException and HttpServerErrorException
- preserve exsisting constructor signatures
- mark HttpHeaders as Serializable
- generate new serialVersionUID where needed
Issue: SPR-7938
The following style updates have been made in anticipation of
substantive changes in subsequent commits:
- organize imports
- correct whitespace errors (leading spaces in code, tabs in Javadoc)
- wrap Javadoc at 90 chars; make imperative ("Return" vs. "Returns")
- use conventional constructor argument wrapping
A serialVersionUID has also been added to RestClientException and its
ResourceAccessException subclass for consistency with the rest of that
same exception hierarchy.
Issue: SPR-7938
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
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
There is usually not need to put annotations on a WebDataBinder
argument in an `@InitBinder` method. However, the presence of any
annotation prevented the successful resolution of the argument.
This fix addresses the issue.
Issue: SPR-8946
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
Reordered inline comments so that they now apply to current
state of the code.
Added logger entry in testlog4j.properties to avoid console
warning.
Issue: SPR-9417
This patch fixes several compiler warnings that do not point to code
problems. Two kinds of warnings are fixed. First in a lot of cases
@SuppressWarnings("unchecked") is used although there are no unchecked
casts happening. This seems to be a leftover from when the code base
was on Java 1.4, now that the code base was moved to Java 1.5 these are
no longer necessary. Secondly there some places where the raw types of
List and Class are used where there wildcard types (List<?> and
Class<?>) would work just as well without causing any raw type warnings.
These changes are beneficial particularly when working in Eclipse or
other IDEs because it reduces 'noise', helping to isolate actual
potential problems in the code.
The following changes have been made:
- remove @SuppressWarnings where no longer needed
- use wildcard types instead of raw types where possible
Previously, if the resolution of a ${...} placeholder resulted in a
valid URL for the location of a log4j properties/XML file, the URL
would ultimately be malformed by an unnecessary call to to
WebUtils#getRealPath.
The implementation of Log4jWebConfigurer#initLogging now eagerly
attempts SystemPropertyUtils#resolvePlaceholders before checking to see
if the location is a valid URL, and bypassing the call to
WebUtils#getRealPath if so.
Issue: SPR-9417
SPR-7591 introduced a java.nio.charset.Charset field within
HttpStatusCodeException. The former is non-serializable, thus by
extension the latter also became non-serializable.
Because the Charset field is only used for outputting the charset name
in HttpStatusCodeException#getResponseBodyAsString, it is reasonable to
store the value returned by Charset#name() instead of the actual Charset
object itself.
This commit refactors HttpStatusCodeException's responseCharset field to
be of type String instead of Charset and adds tests to prove that
HttpStatusCodeException objects are once again serializable as expected.
Issue: SPR-9273, SPR-7591
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
The MappingJacksonHttpMessageConverter now catches all IOException
types raised while reading JSON and translates them into
HttpMessageNotReadableException.
Issue: SPR-9238
The ErrorsMethodArgumentResolver expects the preceding @ModelAttribute
in the controller method signature to be the last one added in the
model -- an assumption that can break if a model attribute is added
earlier (e.g. through a @ModelAttribute method) and more attributes
are added as well. This fix ensures when an @ModelAttribute is resolved
as a controller method argument it has the highest index in the model.
Issue: SPR-9378
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
The fromUri method of UriComponentsBuilder used uri.getXxx() methods,
which decode the URI parts causing URI parsing issues. The same method
now uses uri.getRawXxx().
Issue: SPR-9317
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
When a controller returns a DeferredResult, the underlying async
request will eventually time out. Until now the default behavior was
to send a 503 (SERVICE_UNAVAILABLE). However, this is not desirable
in all cases. For example if waiting on an event, a timeout simply
means there is no new information to send.
To handle those cases a DeferredResult now accespts a timeout result
Object in its constructor. If the timeout occurs before the
DeferredResult is set, the timeout result provided to the constructor
is used instead.
Issue: SPR-8617
* 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