While `HttpHandler` aims to be the most minimal contract across HTTP servers, the
WebHandler API provides essential features commonly used to build web applications.
For example, the `ServerWebExchange` available to WebHandler API components provides
access not only to the request and response, but also to request and session attributes,
access to parsed form data, multipart data, and more.
@ -488,12 +478,14 @@ The table below lists the components that `WebHttpHandlerBuilder` detects:
@@ -488,12 +478,14 @@ The table below lists the components that `WebHttpHandlerBuilder` detects:
| <any>
| `WebExceptionHandler`
| 0..N
| Exception handlers to apply after all ``WebFilter``'s and the target `WebHandler`.
| Provide handling for exceptions from the chain of ``WebFilter``'s and the target
`WebHandler`. For more details, see <<webflux-exception-handler>>.
| <any>
| `WebFilter`
| 0..N
| Filters to invoke before and after the target `WebHandler`.
| Apply interception style logic to before and after the rest of the filter chain and
the target `WebHandler`. For more details, see <<webflux-filters>>.
| "webHandler"
| `WebHandler`
@ -645,9 +637,13 @@ a heartbeat and ignore.
@@ -645,9 +637,13 @@ a heartbeat and ignore.
=== Filters
[.small]#<<web.adoc#filters,Same in Spring MVC>>#
As part of the <<webflux-web-handler-api>>, the `spring-web` module provides a number of
`WebFilter` implementations.
In the <<webflux-web-handler-api>>, a `WebFilter` can be used to apply interception-style
logic before and after the rest of the processing chain of filters and the target
`WebHandler`. When using the <<webflux-config>>, registering a `WebFilter` is as simple
as declaring it as a Spring bean, and optionally expressing precedence via `@Order` on
the bean declaration or by implementing `Ordered`.
The following describe the available `WebFilter` implementations:
[[webflux-filters-forwarded-headers]]
@ -690,6 +686,37 @@ See the section on <<webflux-cors>> and the <<webflux-cors-webfilter>> for more
@@ -690,6 +686,37 @@ See the section on <<webflux-cors>> and the <<webflux-cors-webfilter>> for more
[[webflux-exception-handler]]
=== Exceptions
[.small]#<<web.adoc#mvc-ann-customer-servlet-container-error-page,Same in Spring MVC>>#
In the <<webflux-web-handler-api>>, a `WebExceptionHandler` can be used to to handle
exceptions from the chain of ``WebFilter``'s and the target `WebHandler`. When using the
<<webflux-config>>, registering a `WebExceptionHandler` is as simple as declaring it as a
Spring bean, and optionally expressing precedence via `@Order` on the bean declaration or
by implementing `Ordered`.
Below are the available `WebExceptionHandler` implementations:
by setting the response to the HTTP status code of the exception.
| `WebFluxResponseStatusExceptionHandler`
| Extension of `ResponseStatusExceptionHandler` that can also determine the HTTP status
code an `@ResponseStatus` annotation on any exception.
This handler is declared in the <<webflux-config>>.
|===
[[webflux-dispatcher-handler]]
== DispatcherHandler
@ -805,24 +832,60 @@ processing by writing to the response directly or using a view to render.
@@ -805,24 +832,60 @@ processing by writing to the response directly or using a view to render.
[[webflux-resulthandling]]
=== Result Handling
When `DispatcherHandler` needs to process the return value from a handler, it finds a
`HandlerResultHandler` that support it and invokes it. The available implementations are
listed below with their default order (all are declared in the <<webflux-config>>):
The return value from the invocation of a handler, through a `HandlerAdapter`, is wrapped
as `HandlerResult`, along with some additional context, and passed to the first
`HandlerResultHandler` that claims support for it. The table below shows the available
`HandlerResultHandler` implementations all of which are declared in the <<webflux-config>>:
[cols="1,2,1", options="header"]
|===
| Result Handler Type | Return Values | Default Order
| `ResponseEntityResultHandler`
| `ResponseEntity`, typically from ``@Controller``'s.
| 0
| `ServerResponseResultHandler`
| `ServerResponse`, typically from functional endpoints.
| 0
| `ResponseBodyResultHandler`
| Handle return values from `@ResponseBody` methods or `@RestController` classes.
| 100
| `ViewResolutionResultHandler`
| `CharSequence` or {api-spring-framework}/web/reactive/result/view/View.html[View],
{api-spring-framework}/ui/Model.html[Model] or `Map`,
or any other Object is treated as a model attribute.
Also see <<webflux-viewresolution>>.
| `Integer.MAX_VALUE`
|===
[[webflux-dispatcher-exceptions]]
=== Exceptions
[.small]#<<web.adoc#mvc-exceptionhandlers,Same in Spring MVC>>#
The `HandlerResult` returned from a `HandlerAdapter` may expose a function for error
handling based on some handler-specific mechanism. This error function is called if:
* the handler (e.g. `@Controller`) invocation fails.
* handling of the handler return value through a `HandlerResultHandler` fails.
* `ResponseEntityResultHandler` -- handles `ResponseEntity` return values typically
returned from annotated controllers. The order is set to 0 since it safely matches return
values by type.
* `ServerResponseResultHandler` -- supports `ServerResponse` return values typically
returned from functional endpoints. The order is set to 0 since it safely matches return
values by type.
* `ResponseBodyResultHandler` -- handles return values from `@ResponseBody` methods or
`@RestController` classes. The order is set to 100, i.e. after result handlers that
check for a specific type.
* `ViewResolutionResultHandler` -- performs the <<webflux-viewresolution>> algorithm for
HTML template rendering. The order is set to `Ordered.LOWEST_PRECEDENCE` since it
supports several specific types, e.g. `String`, `Map`, `Rendering`, and others, but will
also treat any other Object as a model attribute. This is why it needs to be last in
the order.
The error function can change the response, e.g. to an error status, as long as an error
signal occurs before the reactive type returned from the handler produces any data items.
This is how `@ExceptionHandler` methods in `@Controller` classes are supported.
By contrast, support for the same in Spring MVC is built on a `HandlerExceptionResolver`.
This generally shouldn't matter, however, keep in mind that in WebFlux you cannot use a
`@ControllerAdvice` to handle exceptions that occur before a handler is chosen.
See also <<webflux-ann-controller-exceptions>> in the Annotated Controller section, or
<<webflux-exception-handler>> in the WebHandler API section.
@ -2159,15 +2222,19 @@ controller method. Use a composite interface if you need to activate multiple vi
@@ -2159,15 +2222,19 @@ controller method. Use a composite interface if you need to activate multiple vi
[[webflux-ann-modelattrib-methods]]
=== Model Methods
=== Model
[.small]#<<web.adoc#mvc-ann-modelattrib-methods,Same in Spring MVC>>#
The `@ModelAttribute` annotation can be used on `@RequestMapping`
<<webflux-ann-modelattrib-method-args,method arguments>> to create or access an Object
from the model and bind it to the request. `@ModelAttribute` can also be used as a
method-level annotation on controller methods whose purpose is not to handle requests
but to add commonly needed model attributes prior to request handling.
The `@ModelAttribute` annotation can be used:
* On a <<webflux-ann-modelattrib-method-args,method argument>> in `@RequestMapping` methods
to create or access an Object from the model, and to bind it to the request through a
`WebDataBinder`.
* As a method-level annotation in `@Controller` or `@ControllerAdvice` classes helping
to initialize the model prior to any `@RequestMapping` method invocation.
* On a `@RequestMapping` method to mark its return value is a model attribute.
This section discusses `@ModelAttribute` methods, or the 2nd from the list above.
A controller can have any number of `@ModelAttribute` methods. All such methods are
invoked before `@RequestMapping` methods in the same controller. A `@ModelAttribute`
method can also be shared across controllers via `@ControllerAdvice`. See the section on
@ -2253,14 +2320,16 @@ as a view name. `@ModelAttribute` can also help to customize the model attribute
@@ -2253,14 +2320,16 @@ as a view name. `@ModelAttribute` can also help to customize the model attribute
[[webflux-ann-initbinder]]
=== Binder Methods
=== DataBinder
[.small]#<<web.adoc#mvc-ann-initbinder,Same in Spring MVC>>#
`@InitBinder` methods in an `@Controller` or `@ControllerAdvice` class can be used to
customize type conversion for method arguments that represent String-based request values
(e.g. request parameters, path variables, headers, cookies, and others). Type conversion
also applies during data binding of request parameters onto `@ModelAttribute` arguments
(i.e. command objects).
`@Controller` or `@ControllerAdvice` classes can have `@InitBinder` methods in order to
initialize instances of `WebDataBinder`, and those in turn are used to:
* Bind request parameters (i.e. form data or query) to a model object.
* Convert String-based request values such as request parameters, path variables,
headers, cookies, and others, to the target type of controller method arguments.
* Format model object values as String values when rendering HTML forms.
`@InitBinder` methods can register controller-specific `java.bean.PropertyEditor`, or
Spring `Converter` and `Formatter` components. In addition, the
@ -507,13 +507,13 @@ declare it as an <<mvc-ann-controller-advice>> bean or configure it directly on
@@ -507,13 +507,13 @@ declare it as an <<mvc-ann-controller-advice>> bean or configure it directly on
[[mvc-exceptionhandlers]]
=== Exception Resolution
=== Exceptions
[.small]#<<web-reactive.adoc#webflux-dispatcher-exceptions,Same in Spring WebFlux>>#
If an exception occurs during the mapping or the invocation of a request handler (e.g. an
`@Controller`), the `DispatcherServlet` delegates to a chain of `HandlerExceptionResolver`
beans to try and resolve the exception and to provide alternative handling for it, which
typically means preparing an error response whether an HTML error page, an error status,
or both.
If an exception occurs during request mapping or is thrown from a request handler such as
an `@Controller`, the `DispatcherServlet` delegates to a chain of `HandlerExceptionResolver`
beans to resolve the exception and provide alternative handling, which typically is an
error response.
The table below lists the available `HandlerExceptionResolver` implementations:
@ -536,29 +536,27 @@ The table below lists the available `HandlerExceptionResolver` implementations:
@@ -536,29 +536,27 @@ The table below lists the available `HandlerExceptionResolver` implementations:
| `ExceptionHandlerExceptionResolver`
| Resolves exceptions by invoking an `@ExceptionHandler` method in an `@Controller` or an
`@ControllerAdvice` class. See <<mvc-ann-exceptionhandler>>.
`@ControllerAdvice` class. See <<mvc-ann-exceptionhandler,@ExceptionHandler methods>>.
|===
[[mvc-excetionhandlers-handling]]
==== Handling
==== Chain of resolvers
You chain exception resolvers by declaring more than one exception resolver beans and,
if necessary, setting the `order` property to specify ordering. Remember, the higher the
order property, the later the exception resolver is positioned in the chain.
You can form an exception resolver chain simply by declaring multiple `HandlerExceptionResolver`
beans in your Spring configuration and setting their `order` properties as needed.
The higher the order property, the later the exception resolver is positioned.
The contract of `HandlerExceptionResolver` specifies that it __can__ return:
The contract of `HandlerExceptionResolver` specifies that it can return:
* `ModelAndView` that points to an error view.
* Empty `ModelAndView` if the exception was handled within the resolver.
* `null` if the exception remains unresolved, for subsequent resolvers to try; if the
exception remains unresolved by any resolver, it is re-thrown and left to propagate to
the Servlet container.
* `null` if the exception remains unresolved, for subsequent resolvers to try; and if the
exception remains at the end, it is allowed to bubble up to the Servlet container.
To configure exception handling is as simple as adding `HandlerExceptionResolver` beans
to your Spring configuration. The <<mvc-config>> automatically declares built-in
resolvers for default Spring MVC exceptions, for `@ResponseStatus` annotated exceptions,
and for support of `@ExceptionHandler` methods. You can customize that list or replace it.
The <<mvc-config>> automatically declares built-in resolvers for default Spring MVC
exceptions, for `@ResponseStatus` annotated exceptions, and for support of
`@ExceptionHandler` methods. You can customize that list or replace it.
[[mvc-ann-customer-servlet-container-error-page]]
@ -2655,15 +2653,19 @@ customized through `jsonpParameterNames` property.
@@ -2655,15 +2653,19 @@ customized through `jsonpParameterNames` property.
[[mvc-ann-modelattrib-methods]]
=== Model Methods
=== Model
[.small]#<<web-reactive.adoc#webflux-ann-modelattrib-methods,Same in Spring WebFlux>>#
The `@ModelAttribute` annotation can be used on `@RequestMapping`
<<mvc-ann-modelattrib-method-args,method arguments>> to create or access an Object
from the model and bind it to the request. `@ModelAttribute` can also be used as a
method-level annotation on controller methods whose purpose is not to handle requests
but to add commonly needed model attributes prior to request handling.
The `@ModelAttribute` annotation can be used:
* On a <<mvc-ann-modelattrib-method-args,method argument>> in `@RequestMapping` methods
to create or access an Object from the model, and to bind it to the request through a
`WebDataBinder`.
* As a method-level annotation in `@Controller` or `@ControllerAdvice` classes helping
to initialize the model prior to any `@RequestMapping` method invocation.
* On a `@RequestMapping` method to mark its return value is a model attribute.
This section discusses `@ModelAttribute` methods, or the 2nd from the list above.
A controller can have any number of `@ModelAttribute` methods. All such methods are
invoked before `@RequestMapping` methods in the same controller. A `@ModelAttribute`
method can also be shared across controllers via `@ControllerAdvice`. See the section on
@ -2728,14 +2730,16 @@ the model attribute name:
@@ -2728,14 +2730,16 @@ the model attribute name:
[[mvc-ann-initbinder]]
=== Binder Methods
=== DataBinder
[.small]#<<web-reactive.adoc#webflux-ann-initbinder,Same in Spring WebFlux>>#
`@InitBinder` methods in an `@Controller` or `@ControllerAdvice` class can be used to
customize type conversion for method arguments that represent String-based request values
(e.g. request parameters, path variables, headers, cookies, and others). Type conversion
also applies during data binding of request parameters onto `@ModelAttribute` arguments
(i.e. command objects).
`@Controller` or `@ControllerAdvice` classes can have `@InitBinder` methods in order to
initialize instances of `WebDataBinder`, and those in turn are used to:
* Bind request parameters (i.e. form data or query) to a model object.
* Convert String-based request values such as request parameters, path variables,
headers, cookies, and others, to the target type of controller method arguments.
* Format model object values as String values when rendering HTML forms.
`@InitBinder` methods can register controller-specific `java.bean.PropertyEditor`, or
Spring `Converter` and `Formatter` components. In addition, the