29.2 The “Spring WebFlux Framework”
Spring WebFlux is the new reactive web framework introduced in Spring Framework 5.0. Unlike Spring MVC, it does not
在spring5.0中介绍,Spring WebFlux 是一个全新的反应式的web框架。不同于
require the Servlet API, is fully asynchronous and non-blocking, and implements
the Reactive Streams specification
spring MVC,它不需要Servelet API,是完全异步,非阻塞的。通过Reactor项目实现Reactive Streams规范。
through the Reactor project.
Spring WebFlux comes in two flavors: functional and annotation-based. The annotation-based one is quite close to the
Spring WebFlux有两种方式:函数和基于注解。基于注解的方式类似于Spring MVC模型,如下示例所示:
Spring MVC model, as shown in the following example:
@RestController
@RequestMapping("/users")
public class MyRestController {
@GetMapping("/{user}")
public Mono<User> getUser(@PathVariable Long user) {
// ...
}
@GetMapping("/{user}/customers")
public Flux<Customer> getUserCustomers(@PathVariable Long user) {
// ...
}
@DeleteMapping("/{user}")
public Mono<User> deleteUser(@PathVariable Long user) {
// ...
}
}
“WebFlux.fn”, the functional variant, separates the routing configuration from the actual handling of the requests, as
“WebFlux.fn”是函数式变体,它将路由配置与请求的实际处理分开,如下示例所示:
shown in the following example:
@Configuration
public class RoutingConfiguration {
@Bean
public RouterFunction<ServerResponse> monoRouterFunction(UserHandler userHandler) {
return route(GET("/{user}").and(accept(APPLICATION_JSON)), userHandler::getUser)
.andRoute(GET("/{user}/customers").and(accept(APPLICATION_JSON)), userHandler::getUserCustomers)
.andRoute(DELETE("/{user}").and(accept(APPLICATION_JSON)), userHandler::deleteUser);
}
}
@Component
public class UserHandler {
public Mono<ServerResponse> getUser(ServerRequest request) {
// ...
}
public Mono<ServerResponse> getUserCustomers(ServerRequest request) {
// ...
}
public Mono<ServerResponse> deleteUser(ServerRequest request) {
// ...
}
}
WebFlux is part of the Spring Framework and detailed information is available in its reference documentation.
WebFlux 是spring框架的一部分,具体信息可以参考reference documentation。
You can define as many RouterFunction beans as you like to modularize the definition of the router. Beans can be ordered if you need to apply a precedence.
您可以根据需要定义尽可能多的RouterFunction bean来模块化路由器的定义。 如果需要应用优先级,可以排序Bean。
To get started, add the spring-boot-starter-webflux module to your application.
添加spring-boot-starter-webflux 来开始你的应用吧。
- Adding both spring-boot-starter-web and spring-boot-starter-webflux modules in your application results in Spring Boot auto-configuring Spring MVC, not WebFlux. This behavior has been chosen because many Spring developers add spring-boot-starter-webflux to their Spring MVC application to use the reactive WebClient. You can still enforce your choice by setting the chosen application type toSpringApplication.setWebApplicationType(WebApplicationType.REACTIVE).
在应用中同时加入 spring-boot-starter-web和 spring-boot-starter-webflux模块会导致spring框架自动配置Spring MVC,而不是WebFlux.选择这种方式是因为很多spring开发者添加spring-boot-starter-webflux 到他们的Spring MVC 应用中以使用反应式WEB客户端。但是你可以通过设置应用类型(SpringApplication.setWebApplicationType(WebApplicationType.REACTIVE).)来强制你的选择。
29.2.1 Spring WebFlux Auto-configuration
Spring Boot provides auto-configuration for Spring WebFlux that works well with most applications.
Springboot 为Spring WebFlux提供自动配置使得与大多数应用能很好的工作在一起。
The auto-configuration adds the following features on top of Spring’s defaults:
自动配置在Spring的默认值之上添加了以下功能:
• Configuring codecs for HttpMessageReader and HttpMessageWriter instances (described later in this document).
为HttpMessageReader 和 HttpMessageWriter配置加解码实例。
• Support for serving static resources, including support for WebJars (described later in this document).
支持提供静态资源,包括支持WebJars。
If you want to keep Spring Boot WebFlux features and you want to add additional WebFlux configuration, you can add
如果你像保持Spring boot WebFlux的特征并且想添加一些额外的WebFlux配置,你可以添加你自己的
your own @Configuration class of type WebFluxConfigurer but without @EnableWebFlux.
类型为WebFluxConfigurer但没有@EnableWebFlux的@congfiguration类。
If you want to take complete control of Spring WebFlux, you can add your own @Configuration annotated
如果你想完全控制Spring WebFlux,你可以添加@Configuration注解和@EnableWebFlux
with @EnableWebFlux.
29.2.2 HTTP Codecs with HttpMessageReaders and HttpMessageWriters
Spring WebFlux uses the HttpMessageReader and HttpMessageWriter interfaces to convert HTTP requests and
Spring WebFlux使用 HttpMessageReader and HttpMessageWriter 接口来转化HTTP请求和响应。
responses. They are configured with CodecConfigurer to have sensible defaults by looking at the libraries available
通过查看类路径中可用的库,它们配置了CodecConfigurer以具有合理的默认值
in your classpath.
Spring Boot applies further customization by using CodecCustomizer instances. For example, spring.jackson.* configuration keys are applied to the Jackson codec.
*Spring Boot通过使用CodecCustomizer实例进一步自定义。例如,spring.jackson.配置键应用Jackson编解码器。
If you need to add or customize codecs, you can create a custom CodecCustomizer component, as shown in the following example:
如果你需要添加或者自定义编解码器,你可以创建一个CodecCustomizer 的类,如下示例所示:
import org.springframework.boot.web.codec.CodecCustomizer;
@Configuration
public class MyConfiguration {
@Bean
public CodecCustomizer myCodecCustomizer() {
return codecConfigurer -> {
// ...
}
}
}
You can also leverage Boot’s custom JSON serializers and deserializers.
29.2.3 Static Content
By default, Spring Boot serves static content from a directory called /static (or /public or /resources or /META-INF/resources) in the classpath. It uses
默认情况下,Spring Boot从类路径中名为/ static(或/ public或/ resources或/ META-INF / resources)的目录中提供静态内容。
theResourceWebHandler from Spring WebFlux so that you can modify that behavior by adding your
own WebFluxConfigurer and overriding the addResourceHandlersmethod.
它使用Spring WebFlux中的ResourceWebHandler,以便您可以通过添加自己的WebFluxConfigurer并覆盖addResourceHandlers方法来修改该行为。
By default, resources are mapped on /******, but you can tune that by setting the spring.webflux.static-path-pattern property. For instance, relocating all resources to /resources/****** can be achieved as follows:
默认情况下,资源映射到/ ******,但您可以通过设置spring.webflux.static-path-pattern属性来调整它。 例如,可以按如下方式将所有资源重新定位到/ resources / ********:
spring.webflux.static-path-pattern=/resources/ **
You can also customize the static resource locations by using spring.resources.static-locations. Doing so replaces the default values with a list of directory locations. If you do so, the default welcome page detection switches
您还可以使用spring.resources.static-locations自定义静态资源位置。 这样做会将默认值替换为目录位置列表。 如果这样做,默认的欢迎页面检测将切换到您的自定义位置。
to your custom locations. So, if there is an index.html in any of your locations on startup, it is the
因此,如果启动时在任何位置存在index.html,则它是应用程序的主页。
home page of the application.
In addition to the “standard” static resource locations listed earlier, a special case is made for Webjars content. Any resources with a path in /webjars/ ** are served from jar files if they are packaged in the Webjars format.
除了前面列出的“标准”静态资源位置之外,还为Webjars内容制作了一个特例。 在/ webjars / **中具有路径的任何资源都是从jar文件提供的,如果它们以Webjars格式打包的话。
- Spring WebFlux applications do not strictly depend on the Servlet API, so they cannot be deployed as war files and do not use the src/main/webappdirectory.
Spring WebFlux应用程序并不严格依赖于Servlet API,因此它们不能作为war文件部署,也不能使用src / main / webapp目录。
29.2.4 Template Engines
As well as REST web services, you can also use Spring WebFlux to serve dynamic HTML content. Spring WebFlux supports a variety of templating technologies, including Thymeleaf, FreeMarker, and Mustache.
和REST Web服务一样,你还可以使用Spring WebFlux来提供动态HTML内容。 Spring WebFlux支持各种模板技术,包括Thymeleaf,FreeMarker和Mustache。
Spring Boot includes auto-configuration support for the following templating engines:
Spring Boot 包括自动装配支持一下模板引擎:
• FreeMarker
• Thymeleaf
• Mustache
When you use one of these templating engines with the default configuration, your templates are picked up automatically from src/main/resources/templates.
当你使用这些中的一个默认配置下的模板引擎时候,您的模板将自动从src / main / resources / templates中选取。
29.2.5 Error Handling
Spring Boot provides a WebExceptionHandler that handles all errors in a sensible way. Its position in the processing
Spring Boot 提供WebExceptionHandler用合适的方式处理所有的错误。它在处理顺序中的位置紧接在
order is immediately before the handlers provided by WebFlux, which are considered last. For machine clients, it
WebFlux提供的处理程序之前,这些处理程序被认为是最后一个。
produces a JSON response with details of the error, the HTTP status, and the exception message. For browser clients,
对于计算机客户端,它会生成一个JSON响应,其中包含错误,HTTP状态和异常消息的详细信息。对于浏览器客户端,
there is a “whitelabel” error handler that renders the same data in HTML format. You can also provide your own HTML
templates to display errors (see the next section).
有一个“whitelabel”错误处理程序,它以HTML格式呈现相同的数据。 您还可以提供自己的HTML用于显示错误的模板(请参阅下一节)。
The first step to customizing this feature often involves using the existing mechanism but replacing or augmenting the error contents. For that, you can add a bean of typeErrorAttributes.
自定义此功能的第一步通常涉及使用现有机制,但替换或扩充错误内容。 为此,您可以添加类型为ErrorAttributes的bean。
To change the error handling behavior, you can implement ErrorWebExceptionHandler and register a bean
要更改错误处理行为,可以实现ErrorWebExceptionHandler并注册该类型的bean定义。
definition of that type. Because a WebExceptionHandleris quite low-level, Spring Boot also provides a
因为WebExceptionHandler是非常底层的,Spring Boot也提供一个便利的
convenient AbstractErrorWebExceptionHandler to let you handle errors in a WebFlux functional way, as
AbstractErrorWebExceptionHandler 让你使用WebFlux函数式的方式处理错误,如下示例所示:
shown in the following example:
public class CustomErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {
// Define constructor here
@Override
protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
return RouterFunctions
.route(aPredicate, aHandler)
.andRoute(anotherPredicate, anotherHandler);
}
}
For a more complete picture, you can also subclass DefaultErrorWebExceptionHandler directly and override specific methods.
要获得更完整的图片,您还可以直接继承DefaultErrorWebExceptionHandler并覆盖特定方法。
Custom Error Pages
If you want to display a custom HTML error page for a given status code, you can add a file to an /error folder. Error
如果要显示给定状态代码的自定义HTML错误页面,可以将文件添加到/ error文件夹。错误页可以是静态的HTML
pages can either be static HTML (that is, added under any of the static resource folders) or built with templates. The
(也就是说,添加在任何静态资源文件夹下)或者使用模板构建。
name of the file should be the exact status code or a series mask.
文件名应该是确切的状态代码或系列掩码。
For example, to map 404 to a static HTML file, your folder structure would be as follows:
比如,映射404到一个静态的HTML文件,你的文件夹结构需要如下:
src/
+- main/
+- java/
| + <source code>
+- resources/
+- public/
+- error/
| +- 404.html
+- <other public assets>
To map all 5xx errors by using a Mustache template, your folder structure would be as follows:
使用Mustache模板来映射所有的5XX的错误,你的文件结构如下:
src/
+- main/
+- java/
| + <source code>
+- resources/
+- templates/
+- error/
| +- 5xx.mustache
+- <other templates>
29.2.6 Web Filters
Spring WebFlux provides a WebFilter interface that can be implemented to filter HTTP request-response
Spring WebFlux 提供WebFilter接口,可以被实现来过滤HTTP请求-响应交换。
exchanges. WebFilter beans found in the application context will be automatically used to filter each exchange.
在应用程序上下文中找到的WebFilter bean将自动用于过滤每个交换。
Where the order of the filters is important they can implement Ordered or be annotated with @Order. Spring Boot
当过滤器顺序很重要的时候,可以是实现Ordered接口或者用@Order注解。
auto-configuration may configure web filters for you. When it does so, the orders shown in the following table will be used:
Spring Boot 自动配置也许会为你配置WEB过滤器。当这样配置后,下表中的顺序将被它们使用。
Web Filter | Order |
---|---|
MetricsWebFilter | Ordered.HIGHEST_PRECEDENCE + 1 |
WebFilterChainProxy(Spring Security) | -100 |
HttpTraceWebFilter | Ordered.LOWEST_PRECEDENCE - 10 |
来自 https://docs.spring.io/spring-boot/docs/2.1.5.RELEASE/reference/htmlsingle/#boot-features-webflux*