@ -1408,18 +1408,18 @@ of `java.util.Optional` in those cases is equivalent to having `required=false`.
@@ -1408,18 +1408,18 @@ of `java.util.Optional` in those cases is equivalent to having `required=false`.
==== Supported method return types
The following are the supported return types:
* A `ModelAndView` object, with the model implicitly enriched with command objects and
* `ModelAndView` object, with the model implicitly enriched with command objects and
the results of `@ModelAttribute` annotated reference data accessor methods.
* A `Model` object, with the view name implicitly determined through a
* `Model` object, with the view name implicitly determined through a
`RequestToViewNameTranslator` and the model implicitly enriched with command objects
and the results of `@ModelAttribute` annotated reference data accessor methods.
* A `Map` object for exposing a model, with the view name implicitly determined through
* `Map` object for exposing a model, with the view name implicitly determined through
a `RequestToViewNameTranslator` and the model implicitly enriched with command objects
and the results of `@ModelAttribute` annotated reference data accessor methods.
* A `View` object, with the model implicitly determined through command objects and
* `View` object, with the model implicitly determined through command objects and
`@ModelAttribute` annotated reference data accessor methods. The handler method may
also programmatically enrich the model by declaring a `Model` argument (see above).
* A `String` value that is interpreted as the logical view name, with the model
* `String` value that is interpreted as the logical view name, with the model
implicitly determined through command objects and `@ModelAttribute` annotated
reference data accessor methods. The handler method may also programmatically enrich
the model by declaring a `Model` argument (see above).
@ -1431,22 +1431,25 @@ The following are the supported return types:
@@ -1431,22 +1431,25 @@ The following are the supported return types:
* If the method is annotated with `@ResponseBody`, the return type is written to the
response HTTP body. The return value will be converted to the declared method argument
type using ``HttpMessageConverter``s. See <<mvc-ann-responsebody>>.
* An `HttpEntity<?>` or `ResponseEntity<?>` object to provide access to the Servlet
* `HttpEntity<?>` or `ResponseEntity<?>` object to provide access to the Servlet
response HTTP headers and contents. The entity body will be converted to the response
stream using ``HttpMessageConverter``s. See <<mvc-ann-httpentity>>.
* An `HttpHeaders` object to return a response with no body.
* A `Callable<?>` can be returned when the application wants to produce the return value
asynchronously in a thread managed by Spring MVC.
* A `DeferredResult<?>` can be returned when the application wants to produce the return
value from a thread of its own choosing.
* A `ListenableFuture<?>` or `CompletableFuture<?>`/`CompletionStage<?>` can be returned
when the application wants to produce the value from a thread pool submission.
* A `ResponseBodyEmitter` can be returned to write multiple objects to the response
* `HttpHeaders` object to return a response with no body.
* `Callable<?>` async computation in a Spring MVC managed thread.
* `DeferredResult<?>` async result produced later from an application managed, or any thread.
* `ListenableFuture<?>` as an alternative equivalent to using `DeferredResult`.
* `CompletableFuture<?>` or `CompletionStage<?>` as an alternative equivalent to `DeferredResult`.
* `ResponseBodyEmitter` can be returned to write multiple objects to the response
asynchronously; also supported as the body within a `ResponseEntity`.
* An `SseEmitter` can be returned to write Server-Sent Events to the response
* `SseEmitter` can be returned to write Server-Sent Events to the response
asynchronously; also supported as the body within a `ResponseEntity`.
* A `StreamingResponseBody` can be returned to write to the response OutputStream
* `StreamingResponseBody` can be returned to write to the response OutputStream
asynchronously; also supported as the body within a `ResponseEntity`.
* Reactive types from Reactor 3, RxJava 2, RxJava 1 or others registered through
the configured `ReactiveAdapterRegistry` can be returned as an alternative
equivalent to using `DeferredResult` for single-valued types, or
`ResponseBodyEmitter` and `SseEmitter` for multi-valued reactive types where a streaming
media type (e.g. "text/event-stream", "application/json+stream") is requested.
* Any other return type is considered to be a single model attribute to be exposed to
the view, using the attribute name specified through `@ModelAttribute` at the method
level (or the default attribute name based on the return type class name). The model
@ -2517,6 +2520,49 @@ Note that `StreamingResponseBody` can also be used as the body in a
@@ -2517,6 +2520,49 @@ Note that `StreamingResponseBody` can also be used as the body in a
the response.
[[mvc-ann-async-reactive-types]]
==== Async Requests with Reactive Types
If using the reactive `WebClient` from `spring-webflux`, or another client, or
a data store with reactive support, you can return reactive types directly from
Spring MVC controller methods.
* If the return type has single-value stream semantics such as Reactor `Mono` or
RxJava `Single` it is adapted and equivalent to using `DeferredResult`.
* If the return type has multi-value stream semantics such as Reactor `Flux` or
RxJava `Observable` / `Flowable` and if the media type indicates streaming, e.g.
"application/stream+json" or "text/event-stream", it is adapted and equivalent to
using `ResponseBodyEmitter` or `SseEmitter`. You can also return
`Flux<ServerSentEvent>` or `Observable<ServerSentEvent>`.
* If the return type has multi-value stream semantics but the media type does not
imply streaming, e.g. "application/json", it is adapted and equivalent to using
`DeferredResult<List<?>>`, e.g. JSON array.
Reactive libraries are detected and adapted to a Reactive Streams `Publisher`
through Spring's pluggable `ReactiveAdapterRegistry` which by default supports
Reactor 3, RxJava 2, and RxJava 1. Note that for RxJava 1 you will need to add