Spring WebFlux, like Spring MVC, is designed in a single point of entry (front controller) pattern, where a central
WebHandler
, DispatcherHandler
, provides the overall request processing algorithm, and the
actual work is done by configurable components -delegates. This model is flexible and supports different workflows.
DispatcherHandler
discovers the delegate beans it needs from the Spring configuration. It is also
designed to act as a Spring bean and implements ApplicationContextAware
to access the context in which
it is running. If DispatcherHandler
is declared with the bean name webHandler
, then it is
in turn discovered by WebHttpHandlerBuilder
, which assembles the request processing chain.
The Spring configuration in a WebFlux application usually contains:
DispatcherHandler
with bean namewebHandler;
WebFilter
andWebExceptionHandler
beans;Special
DispatcherHandler
beans;And more.
The configuration is passed to WebHttpHandlerBuilder
to build the chain processing as shown in the
following example:
ApplicationContext context = ...
HttpHandler handler = WebHttpHandlerBuilder.applicationContext(context).build();
val context: ApplicationContext = ...
val handler = WebHttpHandlerBuilder.applicationContext(context).build()
Received HttpHandler
is ready for use with the server adapter.
1.3.1. Specialized types of beans
DispatcherHandler
delegates to special beans the processing of requests and the
issuance of appropriate responses. By "special beans" we mean Spring-managed Object
instances that
implement WebFlux framework contracts. They typically have built-in contracts, but you can customize their
properties, extend them, or replace them.
The following table lists the special beans that are discovered by
DispatcherHandler
. Note that there are also some other bean types that are defined at a lower level.
Bean type | Explanation |
---|---|
|
Maps a handler request. The mapping is based on some criteria, the details of which depend on the Major |
|
Helps |
|
Processes the result of the handler call and completes the response. |
WebFlux configuration
Applications can declare infrastructure beans that are needed to process requests. However, in most cases the WebFlux configuration is the best starting point. It declares the required beans and provides a higher-level configuration callback API for configuration.
1.3.3. Handling
DispatcherHandler
processes requests as follows:
Each
HandlerMapping
is asked to find a suitable handler and is used the first match.If a handler is found, it is executed through the corresponding
HandlerAdapter
, which exposes the return value after execution asHandlerResult
.HandlerResult
is passed to the correspondingHandlerResultHandler
to complete processing by writing to the response directly or using a rendering view.
1.3.4. Processing the results
The return value after calling the handler
via the HandlerAdapter
is wrapped as a HandlerResult
, along with some additional context,
and passed to the first HandlerResultHandler
, which contains a statement about its support. The
following table shows the available implementations of HandlerResultHandler
, all of which are declared
in the WebFlux configuration:
Result handler type | Return values | Default order |
---|---|---|
|
|
0 |
|
|
0 |
|
Processing return values from methods marked with the |
100 |
|
|
|
Exceptions
The HandlerResult
returned from the HandlerAdapter
may expose
a function for error handling based on some handler-specific mechanism. This error function is called if:
A call to a handler (for example, the
@Controller
annotation) fails.Processing the handler's return value via
HandlerResultHandler
fails.
The error function can change the response (for example, to the error status), provided that the error signal occurs before the reactive type returned by the handler produces any data elements.
Methods annotated
with @ExceptionHandler
in classes annotated with @Controller
are supported this way. In
contrast, their support in Spring MVC is built on HandlerExceptionResolver
. Usually this doesn't
matter. However, be aware that WebFlux cannot use the @ControllerAdvice
annotation to handle exceptions
that occur before the handler is selected.
See: See also the "Exception Management" subsection in the "Annotated Controller" section or the "Exceptions" subsection in the WebHandler API section.
View Recognition
View recognition allows rendering in the browser using HTML -template and model, without tying
you to a specific presentation technology. In Spring WebFlux, view recognition is supported by a special
HandlerResultHandler that uses ViewResolver
instances to map a string (representing the logical name of
the view) to a View
instance. The View
is then used to render the response.
Processing
The HandlerResult
passed to the ViewResolutionResultHandler
contains
the handler's return value and a model containing the attributes added during request processing. The return value
is treated as one of the following:
String
,CharSequence
: The logical name of the view that should be resolved toView
via a list of configuredViewResolver
implementations.void
: Selects the default view name based on the path request, minus the leading and trailing slash, and is resolved inView
. The same thing happens if no view name was specified (for example, a model attribute was returned) or there is an asynchronous return value (for example,Mono
ended empty).Rendering: API for view recognition scripts. Explore the capabilities of your IDE with code completion.
Model
,Map
: Additional model attributes that should be added to model for the request.Any other: Any other return value (other than simple types defined by BeanUtils#isSimpleProperty) is considered a model attribute that must be added to the model. The attribute name is inferred from the class name using conventions if the
@ModelAttribute
handler method annotation is missing.
The model may contain asynchronous, reactive types (for example, from Reactor or RxJava). Before rendering, the
AbstractView
resolves such model attributes to concrete values and updates the model. Single-valued
reactive types resolve to a single value or no value (if empty), and multi-valued reactive types (such as Flux<T>
)
are collected and resolved to List<T>
.
Configuring view recognition is as simple as
adding the ViewResolutionResultHandler
bean to your Spring configuration. WebFlux configuration
provides a dedicated configuration API for recognizing views.
Redirection
The special prefix redirect:
in the view name allows redirection. UrlBasedViewResolver
(and subclasses) recognizes this as an
indication that a redirect is required. The rest of the view name is the redirect URL.
The net result is the
same as if the controller had returned RedirectView
or Rendering.redirectTo("abc").build()
,
but now the controller itself can operate on logical view names. A view name such as
redirect:/some/resource
is specific to the current application, while a view name such as
redirect:https://example.com/arbitrary/path
, redirects to an absolute URL.
Content Negotiation
ViewResolutionResultHandler
supports content negotiation. This handler compares the media types of the
request with the media types supported by each selected View
. The first View
that supports
the requested media type(s) is used.
To support media types such as JSON and XML, Spring WebFlux provides a
HttpMessageWriterView
, which is a special View
that renders via an HttpMessageWriter.
Typically, these views are configured as default views through the WebFlux configuration. Default views are always
selected and used if they match the requested media type.