提交 00b95b10 编写于 作者: R Rossen Stoyanchev

Docs: result handling and view resolution

Issue: SPR-16393
上级 fbde97f3
......@@ -62,6 +62,7 @@ import org.springframework.web.server.ServerWebExchange;
* <li>{@link View} -- View to render with
* <li>{@link Model} -- attributes to add to the model
* <li>{@link Map} -- attributes to add to the model
* <li>{@link Rendering} -- use case driven API for view resolution</li>
* <li>{@link ModelAttribute @ModelAttribute} -- attribute for the model
* <li>Non-simple value -- attribute for the model
* </ul>
......
......@@ -397,6 +397,11 @@ ApplicationContext context = ...
HttpHandler handler = WebHttpHandlerBuilder.applicationContext(context).build()
----
[[webflux-web-handler-api-special-beans]]
==== Special bean types
The table below lists the components that `WebHttpHandlerBuilder` detects:
[cols="2,2,1,3", options="header"]
......@@ -443,7 +448,7 @@ then exposed through methods on `ServerWebExchange`.
[[webflux-form-data]]
==== Form Reader
==== Form data
`ServerWebExchange` exposes the following method for access to form data:
[source,java,indent=0]
......@@ -459,7 +464,7 @@ The `DefaultServerWebExchange` uses the configured `HttpMessageReader` to parse
[[webflux-multipart]]
==== Multipart Reader
==== Multipart data
[.small]#<<web.adoc#mvc-multipart,Same in Spring MVC>>#
`ServerWebExchange` exposes the following method for access to multipart data:
......@@ -587,10 +592,13 @@ The resulting `HttpHandler` is ready for use with a
[.small]#<<web.adoc#mvc-servlet-special-bean-types,Same in Spring MVC>>#
The `DispatcherHandler` delegates to special beans to process requests and render the
appropriate responses. By "special beans" we mean Spring-managed Object instances that
implement one of the framework contracts listed in the table below.
Spring WebFlux provides built-in implementations of these contracts but you can also
customize, extend, or replace them.
appropriate responses. By "special beans" we mean Spring-managed, Object instances that
implement WebFlux framework contracts. Those usually come with built-in contracts but
you can customize their properties, extend then, or replaced.
The table below lists the special beans detected by the `DispatcherHandler`. Note that
there are also some other beans detected at a lower level, see
<<webflux-web-handler-api-special-beans>> in the Web Handler API.
[[webflux-special-beans-table]]
[cols="1,2", options="header"]
......@@ -602,10 +610,10 @@ customize, extend, or replace them.
which vary by `HandlerMapping` implementation -- annotated controllers, simple
URL pattern mappings, etc.
The main `HandlerMapping` implementations are `RequestMappingHandlerMapping` based on
`@RequestMapping` annotated methods, `RouterFunctionMapping` based on functional
endpoint routes, and `SimpleUrlHandlerMapping` based on explicit registrations of URI
path patterns to handlers.
The main `HandlerMapping` implementations are `RequestMappingHandlerMapping` for
`@RequestMapping` annotated methods, `RouterFunctionMapping` for functional endpoint
routes, and `SimpleUrlHandlerMapping` for explicit registrations of URI path patterns
and ``WebHandler``'s.
| HandlerAdapter
| Help the `DispatcherHandler` to invoke a handler mapped to a request regardless of
......@@ -615,25 +623,27 @@ customize, extend, or replace them.
| HandlerResultHandler
| Process the result from the handler invocation and finalize the response.
See <<webflux-resulthandling>>.
The built-in `HandlerResultHandler` implementations are `ResponseEntityResultHandler`
supporting `ResponseEntity` return values, `ResponseBodyResultHandler`
supporting `@ResponseBody` methods, `ServerResponseResultHandler`
supporting the `ServerResponse` returned from functional endpoints, and
`ViewResolutionResultHandler` supporting rendering with a view and a model.
|===
[[webflux-framework-config]]
=== Framework Config
=== WebFlux Config
[.small]#<<web.adoc#mvc-servlet-config,Same in Spring MVC>>#
The `DispatcherHandler` detects the special beans it needs in the `ApplicationContext`.
Applications can declare the special beans they wish to have. However most applications
will find a better starting point in the WebFlux Java config which provide a higher level
configuration API that in turn make the necessary bean declarations.
See <<webflux-config>> for more details.
Applications can declare the infrastructure beans listed under
<<webflux-web-handler-api-special-beans,Web Handler API>> and
<<webflux-special-bean-types,DispatcherHandler>> that are required to process requests.
However in most cases the <<webflux-config>> is the best starting point. It declares the
required beans and provides a higher level configuration callback API to customize it.
[NOTE]
====
Spring Boot relies on the WebFlux config to configure Spring WebFlux and also provides
many extra convenient options.
====
......@@ -651,6 +661,94 @@ 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>>):
* `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.
[[webflux-viewresolution]]
=== View Resolution
[.small]#<<web.adoc#mvc-viewresolver,Same in Spring MVC>>#
View resolution enables rendering to a browser with an HTML template and a model without
tying you to a specific view technology. In Spring WebFlux, view resolution is
supported through the `ViewResolutionResultHandler` that relies on a list of
``ViewResolver``'s to map a String-based view name to a `View` to render the response
with. The <<webflux-config-view-resolvers,WebFlux Config>> can be used to configure the
view resolvers to use.
The `HandlerResult` passed into `ViewResolutionResultHandler` contains the return value
along with a map of attributes (i.e. the model) from the handler. The return value is
then processed as one of the following:
* `String`, `CharSequence` -- a logical view name to be resolved to a `View` through
the list of configured ``ViewResolver``'s.
* `void` or no value (e.g. model attribute returned) -- select default view name based on
the request path minus the leading and trailing slash, and the resolved to a `View`.
* `Model`, `Map` -- attributes to be added to the model.
* {api-spring-framework}/web/reactive/result/view/Rendering.html[Rendering] -- API for
view resolution scenarios; easiest to explore the options with code completion.
* Other -- attribute to be added to the model; the name of the attribute is derived using
Class name conventions, or from a handler method `@ModelAttribute` annotation if present.
The model can contain asynchronous, reactive types (e.g. from Reactor, RxJava). Prior
to rendering, `AbstractView` resolves such model attributes into their concrete values
and updates the model. Single-value reactive types are resolved to a single
value, or no value (if empty) while multi-value reactive types, e.g. `Flux<T>` are
collected and resolved to `List<T>`.
[[webflux-redirecting-redirect-prefix]]
==== Redirect
[.small]#<<web.adoc#mvc-redirecting-redirect-prefix,Same in Spring MVC>>#
The special `redirect:` prefix in a view name allows you to perform a redirect. The
`UrlBasedViewResolver` (and sub-classes) recognize this as an instruction that a
redirect is needed. The rest of the view name is the redirect URL.
The net effect is the same as if the controller had returned a `RedirectView` or
`Rendering.redirectTo("abc").build()`, but now the controller itself can simply
operate in terms of logical view names. A view name such as
`redirect:/some/resource` is relative to the current application, while the view name
`redirect:http://example.com/arbitrary/path` redirects to an absolute URL.
[[webflux-multiple-representations]]
==== Content negotiation
[.small]#<<web.adoc#mvc-multiple-representations,Same in Spring MVC>>#
`ViewResolutionResultHandler` supports content negotiation. It compares the request
media type(s) with the media type(s) supported by each selected `View`. The first `View`
that supports the requested media type(s) is used.
In order to support media types such as JSON and XML, Spring WebFlux provides
`HttpMessageWriterView` which is a special `View` that renders through an
<<webflux-codecs,HttpMessageWriter>>. Typically you would configure these as default
views through the <<webflux-config-view-resolvers,WebFlux Config>>. Default views are
always selected and used if they match the requested media type.
[[webflux-controller]]
== Annotated Controllers
[.small]#<<web.adoc#mvc-controller,Same in Spring MVC>>#
......@@ -1105,12 +1203,12 @@ generally supported for all return values.
|Controller method return value|Description
|`@ResponseBody`
|The return value is encoded through ``HttpMessageWriter``s and written to the response.
|The return value is encoded through ``HttpMessageWriter``'s and written to the response.
See <<webflux-ann-responsebody>>.
|`HttpEntity<B>`, `ResponseEntity<B>`
|The return value specifies the full response including HTTP headers and body be encoded
through ``HttpMessageWriter``s and written to the response.
through ``HttpMessageWriter``'s and written to the response.
See <<webflux-ann-responseentity>>.
|`HttpHeaders`
......
......@@ -219,10 +219,11 @@ If an application context hierarchy is not required, applications may configure
[.small]#<<web-reactive.adoc#webflux-special-bean-types,Same in Spring WebFlux>>#
The `DispatcherServlet` delegates to special beans to process requests and render the
appropriate responses. By "special beans" we mean Spring-managed Object instances that
implement one of the framework contracts listed in the table below.
Spring MVC provides built-in implementations of these contracts but you can also
customize, extend, or replace them.
appropriate responses. By "special beans" we mean Spring-managed, Object instances that
implement WebFlux framework contracts. Those usually come with built-in contracts but
you can customize their properties, extend then, or replaced.
The table below lists the special beans detected by the `DispatcherHandler`:
[[mvc-webappctx-special-beans-tbl]]
[cols="1,2", options="header"]
......@@ -273,28 +274,29 @@ customize, extend, or replace them.
[[mvc-servlet-config]]
=== Framework Config
=== Web MVC Config
[.small]#<<web-reactive.adoc#webflux-framework-config,Same in Spring WebFlux>>#
For each type of special bean, the `DispatcherServlet` checks for the `WebApplicationContext` first.
If there are no matching bean types, it falls back on the default types listed in
Applications can declare the infrastructure beans listed in <<mvc-special-bean-types>>
that are required to process requests. The `DispatcherServlet` checks the
`WebApplicationContext` for each special bean. If there are no matching bean types, it
falls back on the default types listed in
https://github.com/spring-projects/spring-framework/blob/master/spring-webmvc/src/main/resources/org/springframework/web/servlet/DispatcherServlet.properties[DispatcherServlet.properties].
Applications can declare the special beans they wish to have. Most applications however
will find a better starting point in the MVC Java config or the MVC XML namespace which
provide a higher level configuration API that in turn make the necessary bean declarations.
See <<mvc-config>> for more details.
In most cases the <<mvc-config>> is the best starting point. It declares the required
beans in either Java or XML, and provides a higher level configuration callback API to
customize it.
[NOTE]
====
Spring Boot relies on the MVC Java config to configure Spring MVC and also
provides many extra convenient options on top.
provides many extra convenient options.
====
[[mvc-container-config]]
=== Container Config
=== Servlet Config
In a Servlet 3.0+ environment, you have the option of configuring the Servlet container
programmatically as an alternative or in combination with a `web.xml` file. Below is an
......@@ -506,6 +508,7 @@ declare it as an <<mvc-ann-controller-advice>> bean or configure it directly on
[[mvc-viewresolver]]
=== View Resolution
[.small]#<<web-reactive.adoc#webflux-viewresolution,Same in Spring WebFlux>>#
Spring MVC defines the `ViewResolver` and `View` interfaces that enable you to render
models in a browser without tying you to a specific view technology. `ViewResolver`
......@@ -569,17 +572,18 @@ indicate the view could not be found. However in the case of JSPs, and
perform a dispatch through `RequestDispatcher`. There an `InternalResourceViewResolver`
must always be configured last in the order.
See <<mvc-config-view-controller,View Controllers>> under <<mvc-config>> for details on
how to configure view resolution. Also see<<mvc-view>> for more details on supported
view technologies.
See <<mvc-config-view-resolvers>> and <<mvc-config-view-controller,View Controllers>>
under <<mvc-config>> for details on how to configure view resolution. Also see
<<mvc-view>> for more details on supported view technologies.
[[mvc-redirecting-redirect-prefix]]
==== Redirect
[.small]#<<web-reactive.adoc#webflux-redirecting-redirect-prefix,Same in Spring WebFlux>>#
The special `redirect:` prefix in a view name allows you to perform a redirect. The
`UrlBasedViewResolver` (and subclasses) will recognize this as a special indication that a
redirect is needed. The rest of the view name will be treated as the redirect URL.
`UrlBasedViewResolver` (and sub-classes) recognize this as an instruction that a
redirect is needed. The rest of the view name is the redirect URL.
The net effect is the same as if the controller had returned a `RedirectView`, but now
the controller itself can simply operate in terms of logical view names. A logical view
......@@ -605,6 +609,7 @@ Servlet/JSP engine. Note that you may also chain multiple view resolvers, instea
[[mvc-multiple-representations]]
==== Content negotiation
[.small]#<<web-reactive.adoc#webflux-multiple-representations,Same in Spring WebFlux>>#
{api-spring-framework}/web/servlet/view/ContentNegotiatingViewResolver.html[ContentNegotiatingViewResolver]
does not resolve views itself but rather delegates
......@@ -3481,7 +3486,7 @@ The async request processing feature must be enabled at the Servlet container le
The MVC config also exposes several options for asynchronous requests.
[[mvc-ann-async-configuration-spring-mvc]]
[[mvc-ann-async-configuration-servlet3]]
==== Servlet container
Filter and Servlet declarations have an `asyncSupported` that needs to be set to true
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册