Generally update chapter and add documentation for 4.2 including
the return value types ResponseBodyEmitter, SseEmitter, and
StreamingResponseBody.
Issue: SPR-12672
Server-sent events is a just another variation on the same "HTTP Streaming"
technique except events pushed from the server are formatted according to
the W3C Servet-Sent Events specification.
Server-Sent Events can be used for their intended purpose, that is to push
events from the server to clients. It is quite easy to do in Spring MVC and
requires simply returning a value of type `SseEmitter`.
Note however that Internet Explorer does not support Server-Sent Events and
that for more advanced web application messaging scenarios such as online games,
collaboration, financial applicatinos, and others it's better to consider
Spring's WebSocket support that includes SockJS-style WebSocket emulation
falling back to a very wide range of browsers (including Internet Explorer)
and also higher-level messaging patterns for interacting with clients through
a publish-subscribe model within a more messaging-centric architecture.
For further background on this see
http://blog.pivotal.io/pivotal/products/websocket-architecture-in-spring-4-0[the following blog post].
[[mvc-ann-async-output-stream]]
==== HTTP Streaming Directly To The OutputStream
`ResponseBodyEmitter` allows sending events by writing Objects to the
response through an `HttpMessageConverter`. This is probably the most common
case, for example when writing JSON data. However sometimes it is useful to
bypass message conversion and write directly to the response `OutputStream`
for example for a file download. This can be done with the help of the
`StreamingResponseBody` return value type.
Here is an example of that:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@RequestMapping("/download")
public StreamingResponseBody handle() {
return new StreamingResponseBody() {
@Override
public void writeTo(OutputStream outputStream) throws IOException {
// write...
}
};
}
----
Note that `StreamingResponseBody` can also be used as the body in a
`ResponseEntity` in order to customize the status and headers of
the response.
[[mvc-ann-async-configuration]]
==== Configuration for Async Request Processing
==== Configuring Asynchronous Request Processing
[[mvc-ann-async-configuration-servlet3]]
===== Servlet 3 Async Config
To use Servlet 3 async request processing, you need to update `web.xml` to version 3.0:
===== Servlet Container Configuration
For applications configured with a `web.xml` be sure to update to version 3.0:
[source,xml,indent=0]
[subs="verbatim,quotes"]
@ -2209,22 +2294,15 @@ To use Servlet 3 async request processing, you need to update `web.xml` to versi
@@ -2209,22 +2294,15 @@ To use Servlet 3 async request processing, you need to update `web.xml` to versi
</web-app>
----
The `DispatcherServlet` and any `Filter` configuration need to have the
`<async-supported>true</async-supported>` sub-element. Additionally, any `Filter` that
also needs to get involved in async dispatches should also be configured to support the
ASYNC dispatcher type. Note that it is safe to enable the ASYNC dispatcher type for all
filters provided with the Spring Framework since they will not get involved in async
dispatches unless needed.
Asynchronous support must be enabled on the `DispatcherServlet` through the
any `Filter` that participates in asyncrequest processing must be configured
to support the ASYNC dispatcher type. It should be safe to enable the ASYNC
dispatcher type for all filters provided with the Spring Framework since they
usually extend `OncePerRequestFilter` and that has runtime checks for whether
the filter needs to be involved in async dispatches or not.
[WARNING]
====
Note that for some Filters it is absolutely critical to ensure they are mapped to
be invoked during asynchronous dispatches. For example if a filter such as the
`OpenEntityManagerInViewFilter` is responsible for releasing database connection
resources and must be invoked at the end of an async request.
Below is an example of a propertly configured filter:
====
Below is some example web.xml configuration:
[source,xml,indent=0]
[subs="verbatim,quotes"]
@ -2253,18 +2331,20 @@ Below is an example of a propertly configured filter:
@@ -2253,18 +2331,20 @@ Below is an example of a propertly configured filter:
----
If using Servlet 3, Java based configuration, e.g. via `WebApplicationInitializer`,
If using Servlet 3, Java based configuration for example via `WebApplicationInitializer`,
you'll also need to set the "asyncSupported" flag as well as the ASYNC dispatcher type
just like with `web.xml`. To simplify all this configuration, consider extending
`AbstractDispatcherServletInitializer` or
`AbstractAnnotationConfigDispatcherServletInitializer`, which automatically set those
options and make it very easy to register `Filter` instances.
`AbstractAnnotationConfigDispatcherServletInitializer` which automatically
set those options and make it very easy to register `Filter` instances.
[[mvc-ann-async-configuration-spring-mvc]]
===== Spring MVC Async Config
The MVC Java config and the MVC namespace both provide options for configuring async
request processing. `WebMvcConfigurer` has the method `configureAsyncSupport` while
<mvc:annotation-driven> has an <async-support> sub-element.
===== Spring MVC Configuration
The MVC Java config and the MVC namespace provide options for configuring
asynchronous request processing. `WebMvcConfigurer` has the method
`configureAsyncSupport` while `<mvc:annotation-driven>` has an
`<async-support>` sub-element.
Those allow you to configure the default timeout value to use for async requests, which
if not set depends on the underlying Servlet container (e.g. 10 seconds on Tomcat). You