Commit Graph

57 Commits

Author SHA1 Message Date
Rossen Stoyanchev
529e62921d Refactor Servlet 3 async support
As a result of the refactoring, the AsyncContext dispatch mechanism is
used much more centrally. Effectively every asynchronously processed
request involves one initial (container) thread, a second thread to
produce the handler return value asynchronously, and a third thread
as a result of a dispatch back to the container to resume processing
of the asynchronous resuilt.

Other updates include the addition of a MockAsyncContext and support
of related request method in the test packages of spring-web and
spring-webmvc. Also an upgrade of a Jetty test dependency required
to make tests pass.

Issue: SPR-9433
2012-08-03 19:15:53 -04:00
Rossen Stoyanchev
914557b975 Use a default for INTROSPECT_TYPE_LEVEL_MAPPING
Usually this request attribute is set for all sub-classes of
AbstractUrlHandlerMapping and therefore whenever
AnnotationMethodHandlerAdapter is used. However, having a
default value to fall back on in AnnotationMethodHandlerAdapter
is still appropriate in general and also considering the Javadoc
of HandlerMapping.INTROSPECT_TYPE_LEVEL_MAPPING.

Issue: SPR-9629
2012-07-25 19:22:15 -04:00
Rossen Stoyanchev
64d939bb16 Add ContentNegotiationManagerFactoryBean
The new FactoryBean facilitates the creation of a
ContentNegotiationManager in XML configuration.

Issue: SPR-8420
2012-07-21 06:16:42 -04:00
Rossen Stoyanchev
028e15faa3 Add options to configure content negotiation
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
2012-07-20 21:32:02 -04:00
Rossen Stoyanchev
92759ed1f8 Add exclude patterns for mapped interceptors
Add the ability provide exclude patterns for mapped interceptors in the
MVC namespace and in the MVC Java config.

Issue: SPR-6570
2012-07-20 14:47:46 -04:00
Rossen Stoyanchev
6cc512b51c Ensure async Callables are in sync with the call stack
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
2012-07-20 12:50:01 -04:00
Rossen Stoyanchev
d3d00696a4 Create StandardServletAsyncWebRequest via reflection
Issue: SPR-9500
2012-07-18 10:02:15 -04:00
Rossen Stoyanchev
eab6e1d134 Parameterize DeferredResult
Issue: SPR-9579
2012-07-18 09:43:03 -04:00
Rossen Stoyanchev
a1b7a314c1 Add BindException to DefaultHandlerExceptionResolver
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
2012-07-10 17:32:13 -04:00
Rossen Stoyanchev
e860fa9a8b Move feed message converters ahead of jackson/jaxb2
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
2012-07-10 17:12:06 -04:00
Rossen Stoyanchev
cf147a82ef Fix issue with incorrect class import
Issue: SPR-9112
2012-07-09 20:34:05 -04:00
Rossen Stoyanchev
c846198e46 Add support for global @ExceptionHandler methods
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
2012-07-09 17:27:03 -04:00
Juergen Hoeller
d97a4b5b3c polishing 2012-07-05 00:31:51 +02:00
Rossen Stoyanchev
e870c9a392 Reduce logging in HandlerExecutionChain
Before this change the HandlerExecitionChain logged errors each time a
an AsyncHandlerInterceptor returned a null async Callable, a condition
which is acceptable.

SPR-9524
2012-07-02 17:56:39 -04:00
Chris Beams
dc822cdca0 Reflect 3.2=>3.1.2 backports in @since tags etc
Issue: SPR-9443, SPR-6847, SPR-9446, SPR-9444, SPR-9439, SPR-9302,
       SPR-9507, SPR-9238, SPR-9397, SPR-9406, SPR-9502
2012-06-27 23:07:48 +02:00
Rossen Stoyanchev
7dff02b2c1 Fix import issue introduced in prior commit
Issue: SPR-9289
2012-06-26 18:07:12 -04:00
Rossen Stoyanchev
3f5fa44d32 Polish PathVariableMapMethodArgumentResolver
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
2012-06-26 10:23:01 -04:00
Rossen Stoyanchev
4fd7645efd Enable smart suffix pattern match for request mapping
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
2012-06-25 21:30:10 -04:00
Rossen Stoyanchev
f94aed8386 Polish ContentNegotiationStrategy support
Issue: SPR-8410, SPR-8417, SPR-8418,SPR-8416, SPR-8419,SPR-7722
2012-06-25 15:24:05 -04:00
Rossen Stoyanchev
a0747458e7 Add support for HTTP PATCH method
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
2012-06-22 16:57:22 -04:00
Rossen Stoyanchev
f05e2bc56f Add abstractions for content negotiation
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
2012-06-22 11:55:46 -04:00
Rossen Stoyanchev
4027b38903 Merge rather than add URI vars to data binding values
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
2012-05-23 18:50:43 -04:00
Arjen Poutsma
f64c13ad2e Add convenient WebAppInitializer base classes
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
2012-05-22 17:31:55 +03:00
Rossen Stoyanchev
77ae101402 Add required flag to @RequestBody
If true and there is no body => HttpMessageNotReadableException
If false and there is no body, the argument resolves to null.

Issue: SPR-9239
2012-05-17 17:48:48 -04:00
Rossen Stoyanchev
0105c5ebb9 Decode path vars in pre-3.1 @MVC support clases too
See the commit comments for:
57307a0b2e

This commit also applies the change to pre-3.1 `@MVC` suppor classes.

Issue: SPR-6951
2012-05-17 16:35:55 -04:00
Rossen Stoyanchev
57307a0b2e Decode path vars when url decoding is turned off
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
2012-05-17 16:01:20 -04:00
Rossen Stoyanchev
cf5d55173b Pattern suffix issue in AnnotationMethodHandlerAdapter
SPR-9333
2012-05-16 13:22:50 -04:00
Rossen Stoyanchev
01a9dd9772 Add option to set Content-Length in JSON Views
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
2012-05-15 18:10:24 -04:00
Rossen Stoyanchev
2af294ab26 Add MessageCodesResolver hook to WebMvcConfigurer
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
2012-05-15 17:11:28 -04:00
Rossen Stoyanchev
bdc3599d3d Add CompositeRequestCondition
The new type makes it easier providing multiple custom request mapping
conditions via setters on RequestMappingHandlerMapping.

Issue: SPR-9350
2012-05-15 13:16:06 -04:00
Rossen Stoyanchev
fbb2103e4d Add "excludedExceptions" to SimpleUrlHandlerMapping
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
2012-05-15 13:16:06 -04:00
Rossen Stoyanchev
1d0e484eac Support access to all URI vars via @PathVariable Map
Issue: SPR-9289
2012-05-14 16:01:16 -04:00
Rossen Stoyanchev
59084354e2 Add validation of HTTP method in form tag
SPR-6945
2012-05-14 11:38:58 -04:00
Rossen Stoyanchev
d52fc3bd2f Prevent response updates if @ResponseStatus has reason
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
2012-05-11 17:41:14 -04:00
Rossen Stoyanchev
c57d4e2386 Add trySet method to DeferredResult
The method absorbs any potential StaleAsyncWebRequestException and
returns false instead.

Issue: SPR-8517
2012-05-11 16:07:56 -04:00
Rossen Stoyanchev
982cb2f258 Fix content negotiation issue with sort by q-value
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
2012-05-11 14:43:58 -04:00
Rossen Stoyanchev
d7efc0db80 Detect controller methods via InitializingBean hook
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
2012-05-10 16:42:36 -04:00
Rossen Stoyanchev
f61f4a960e Discover controllers based on type @RequestMapping
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
2012-05-10 16:19:14 -04:00
Rossen Stoyanchev
e04b322110 Don't decode URI for content negotiation by extension
Minor bug fix in the ContentNegotiatingViewResolver where decoding the
URI prevented proper detection of the file extension in a URL.

Issue: SPR-9390
2012-05-10 15:00:01 -04:00
Rossen Stoyanchev
db289495e5 Pretty print option for Jackson converter and view
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
2012-05-09 16:29:22 -04:00
Rossen Stoyanchev
e63ca04fdb Add Jackson 2 HttpMessageConverter and View
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
2012-05-09 13:07:25 -04:00
Rossen Stoyanchev
e7506b50b2 HanderInterceptor and OSIV async request changes
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
2012-05-04 16:12:14 -04:00
Rossen Stoyanchev
1eaaa9a446 Add empty location check to ResourceHttpRequestHandler
ResourceHttpRequestHandler now implements InitializingBean and
checks for empty locations.

Issue: SPR-9186
2012-05-01 17:08:19 -04:00
Stevo Slavic
effb762558 Fix javadoc warnings
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
2012-04-30 11:31:02 +03:00
Rossen Stoyanchev
f37efb4279 Polish Servlet async request processing
* 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
2012-04-23 12:50:45 -04:00
Rossen Stoyanchev
3642b0f365 Initial cut of Servlet 3.0 based async support
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
2012-04-18 16:36:09 -04:00
Rossen Stoyanchev
cfe2af7690 Use the type of the actual return value in @MVC
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
2012-04-06 16:50:22 -04:00
Rossen Stoyanchev
97c22fc08e Minor improvement in ExceptionHandlerExceptionResolver
Moved a null check inside a protected method to give protected method
a chance to override what happens in that case.

Issues: SPR-9193
2012-04-06 14:06:23 -04:00
Rossen Stoyanchev
ca8b98e947 Fix issue with parsing media types
Invalid Content-Type or Accept header values previously resulted in the
IllegalArgumentException getting propagated. After this change such
errors are detected and generally treated as a "no match", which
may for example result in a 406 in the case of the Accept header.

Issue: SPR-9148
2012-04-02 17:36:23 -04:00
Rossen Stoyanchev
0b02933938 Fix race condition in AnntationMethodHER
Issues: SPR-9138
2012-04-02 15:46:31 -04:00