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.
GO TO FULL VERSION