Commit Graph

66 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
Sam Brannen 37dc211f58 Support named dispatchers in MockServletContext
Currently the getNamedDispatcher(String) method of MockServletContext
always returns null. This poses a problem in certain testing scenarios
since one would always expect at least a default Servlet to be present.
This is specifically important for web application tests that involve
the DefaultServletHttpRequestHandler which attempts to forward to the
default Servlet after retrieving it by name. Furthermore, there is no
way to register a named RequestDispatcher with the MockServletContext.

This commit addresses these issues by introducing the following in
MockServletContext.

 - a new defaultServletName property for configuring the name of the
   default Servlet, which defaults to "default"
 - named RequestDispatchers can be registered and unregistered
 - a MockRequestDispatcher is registered for the "default" Servlet
   automatically in the constructor
 - when the defaultServletName property is set to a new value the
   the current default RequestDispatcher is unregistered and replaced
   with a MockRequestDispatcher for the new defaultServletName

Issue: SPR-9587
2012-07-26 03:06:07 +02: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 7c6a1a1bf0 Improve tests for detection of @MVC annotations
Issue: SPR-9601
2012-07-25 19:10:46 -04:00
Sam Brannen 060b37ca8d Fix typo in MockFilterChain 2012-07-25 01:03:33 +02: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
Chris Beams 2a2b6eef91 Introduce ConfigurableWebEnvironment
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
2012-05-26 14:35:57 +03:00
Chris Beams 9fcfd7e827 Introduce ConfigurableEnvironment#merge
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
2012-05-26 14:33:53 +03:00
Chris Beams 5874383ef0 Polish
Issue: SPR-9439
2012-05-26 14:33:52 +03: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
Chris Beams f3bcb6e2e4 Update spring.schemas to reflect 3.2 schemas
Commit 180c5b2ef6 introduced 3.2 versions
of all spring-* schemas; this commit updates spring.schemas mapping
files to include these new versions.
2012-05-18 14:31:33 +03:00
Sam Brannen 09d98fd3ae Delete superfluous fail() invocations in RequestResponseBodyMethodProcessorTests
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.
2012-05-18 03:10:13 +02: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