DispatcherHandler

Spring WebFlux 与 Spring MVC 类似,围绕前端控制器模式设计,其中一个中央 WebHandler(即 DispatcherHandler)为请求处理提供了一个共享算法,而实际工作则由可配置的委托组件执行。此模型很灵活,支持多种工作流。

DispatcherHandler 从 Spring 配置中发现它需要的委托组件。它还被设计为一个 Spring bean 本身,并实现 ApplicationContextAware 以访问其运行的上下文。如果 DispatcherHandler 以 bean 名称 webHandler 声明,则它反过来会被 WebHttpHandlerBuilder 发现,后者会组合一个请求处理链,如 WebHandler API 中所述。

WebFlux 应用程序中的 Spring 配置通常包含

配置提供给 WebHttpHandlerBuilder 以构建处理链,如下例所示

  • Java

  • Kotlin

ApplicationContext context = ...
HttpHandler handler = WebHttpHandlerBuilder.applicationContext(context).build();
val context: ApplicationContext = ...
val handler = WebHttpHandlerBuilder.applicationContext(context).build()

生成的 HttpHandler 已准备好与 服务器适配器 一起使用。

特殊 Bean 类型

DispatcherHandler 委托给特殊 bean 来处理请求并呈现适当的响应。所谓“特殊 bean”,是指实现 WebFlux 框架契约的 Spring 管理的 Object 实例。这些通常带有内置契约,但你可以自定义它们的属性、扩展它们或替换它们。

下表列出了 DispatcherHandler 检测到的特殊 bean。请注意,在较低级别还检测到一些其他 bean(请参阅 Web 处理程序 API 中的 特殊 bean 类型)。

Bean 类型 说明

HandlerMapping

将请求映射到处理程序。映射基于某些条件,具体细节因 HandlerMapping 实现而异,包括带注释的控制器、简单的 URL 模式映射等。

主要的 HandlerMapping 实现包括用于 @RequestMapping 带注释方法的 RequestMappingHandlerMapping、用于函数端点路由的 RouterFunctionMapping,以及用于 URI 路径模式和 WebHandler 实例的显式注册的 SimpleUrlHandlerMapping

HandlerAdapter

帮助 DispatcherHandler 调用映射到请求的处理程序,而不管实际如何调用处理程序。例如,调用带注释的控制器需要解析注释。HandlerAdapter 的主要目的是保护 DispatcherHandler 不受此类细节的影响。

HandlerResultHandler

处理处理程序调用的结果并完成响应。请参阅 结果处理

WebFlux 配置

应用程序可以声明处理请求所需的(在 Web 处理程序 APIDispatcherHandler 下列出的)基础设施 bean。但是,在大多数情况下,WebFlux 配置 是最佳起点。它声明所需的 bean,并提供更高级别的配置回调 API 来对其进行自定义。

Spring Boot 依赖于 WebFlux 配置来配置 Spring WebFlux,还提供了许多额外的便捷选项。

处理

DispatcherHandler 如下处理请求

  • 要求每个 HandlerMapping 查找匹配的处理程序,并使用第一个匹配项。

  • 如果找到处理程序,则通过适当的 HandlerAdapter 运行它,该 HandlerAdapter 将执行的返回值作为 HandlerResult 公开。

  • HandlerResult 交给适当的 HandlerResultHandler,通过直接写入响应或使用视图进行渲染来完成处理。

结果处理

通过 HandlerAdapter 调用处理程序的返回值作为 HandlerResult 封装,并附带一些其他上下文,然后传递给第一个声明支持它的 HandlerResultHandler。下表显示了可用的 HandlerResultHandler 实现,所有这些实现都在 WebFlux 配置 中声明

结果处理程序类型 返回值 默认顺序

ResponseEntityResultHandler

ResponseEntity,通常来自 @Controller 实例。

0

ServerResponseResultHandler

ServerResponse,通常来自函数端点。

0

ResponseBodyResultHandler

处理 @ResponseBody 方法或 @RestController 类的返回值。

100

ViewResolutionResultHandler

CharSequenceViewModelMapRendering 或任何其他 Object 都被视为模型属性。

另请参见 视图解析

Integer.MAX_VALUE

异常

HandlerAdapter 实现可以内部处理调用请求处理程序(例如控制器方法)的异常。但是,如果请求处理程序返回异步值,则可能会延迟异常。

HandlerAdapter 可以将其异常处理机制公开为在其返回的 HandlerResult 上设置的 DispatchExceptionHandler。设置后,DispatcherHandler 也会将其应用于结果的处理。

HandlerAdapter 也可以选择实现 DispatchExceptionHandler。在这种情况下,DispatcherHandler 会将其应用于在映射处理程序之前出现的异常,例如在处理程序映射期间或更早,例如在 WebFilter 中。

另请参见“带注释的控制器”部分中的 异常 或 WebHandler API 部分中的 异常

视图解析

视图解析支持使用 HTML 模板和模型向浏览器渲染,而无需将您绑定到特定的视图技术。在 Spring WebFlux 中,视图解析通过一个专门的 HandlerResultHandler 来支持,该 HandlerResultHandler 使用 `ViewResolver` 实例将一个字符串(表示逻辑视图名称)映射到一个 `View` 实例。然后使用 `View` 来渲染响应。

处理

传递到 `ViewResolutionResultHandler` 中的 `HandlerResult` 包含从处理程序返回的值和在请求处理期间添加的属性的模型。返回值将被处理为以下之一

  • StringCharSequence:一个逻辑视图名称,将通过已配置的 `ViewResolver` 实现列表解析为 `View`。

  • void:根据请求路径(减去前导和尾随斜杠)选择一个默认视图名称,并将其解析为 `View`。当未提供视图名称(例如,返回了模型属性)或异步返回值(例如,`Mono` 完成为空)时,也会发生相同的情况。

  • 渲染:视图解析场景的 API。使用代码补全功能在 IDE 中浏览选项。

  • ModelMap:要添加到请求模型的额外模型属性。

  • 任何其他:任何其他返回值(除了简单类型,如 BeanUtils#isSimpleProperty 所确定的)都被视为要添加到模型的模型属性。属性名称是通过使用 约定 从类名派生的,除非存在处理程序方法 `@ModelAttribute` 注释。

该模型可以包含异步、反应式类型(例如,来自 Reactor 或 RxJava)。在渲染之前,`AbstractView` 将此类模型属性解析为具体值并更新模型。单值反应式类型解析为单个值或无值(如果为空),而多值反应式类型(例如,`Flux<T>`)被收集并解析为 `List<T>`。

要配置视图解析,只需向 Spring 配置中添加一个 ViewResolutionResultHandler bean。 WebFlux 配置 提供了一个专门的配置 API,用于视图解析。

有关与 Spring WebFlux 集成的视图技术,请参阅 视图技术

重定向

视图名称中的特殊 redirect: 前缀允许您执行重定向。 UrlBasedViewResolver(和子类)将其识别为需要重定向的指令。视图名称的其余部分是重定向 URL。

最终效果与控制器返回 RedirectViewRendering.redirectTo("abc").build() 相同,但现在控制器本身可以根据逻辑视图名称进行操作。诸如 redirect:/some/resource 的视图名称相对于当前应用程序,而诸如 redirect:https://example.com/arbitrary/path 的视图名称重定向到绝对 URL。

内容协商

ViewResolutionResultHandler 支持内容协商。它将请求媒体类型与每个选定的 View 支持的媒体类型进行比较。使用支持所请求媒体类型的第一个 View

为了支持 JSON 和 XML 等媒体类型,Spring WebFlux 提供了 HttpMessageWriterView,它是一个特殊的 View,通过 HttpMessageWriter 渲染。通常,您会通过 WebFlux 配置 将这些配置为默认视图。如果默认视图与所请求的媒体类型匹配,则始终选择并使用它们。