|
对于最新的稳定版本,请使用 Spring Framework 7.0.6! |
WebFlux配置
启用WebFlux配置
您可以使用@EnableWebFlux注解在您的Java配置中,如下例所示:
-
Java
-
Kotlin
@Configuration
@EnableWebFlux
public class WebConfig {
}
@Configuration
@EnableWebFlux
class WebConfig
上一个示例注册了多个Spring WebFlux 基础结构bean,并根据类路径上可用的依赖进行适应 — 对于JSON、XML和其他格式。
WebFlux配置API
在你的Java配置中,你可以实现WebFluxConfigurer接口,
如下例所示:
-
Java
-
Kotlin
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
// Implement configuration methods...
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
// Implement configuration methods...
}
转换与格式化
默认情况下,已安装各种数字和日期类型的格式化程序,并通过字段上的@NumberFormat和@DateTimeFormat支持自定义。
要在Java配置中注册自定义格式化程序和转换器,请使用以下方法:
-
Java
-
Kotlin
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
// ...
}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
override fun addFormatters(registry: FormatterRegistry) {
// ...
}
}
默认情况下,Spring WebFlux 在解析和格式化日期值时会考虑请求的区域设置。这对于日期以字符串形式表示的表单有效,这些字符串在“input”表单字段中输入。然而,对于“date”和“time”表单字段,浏览器使用 HTML 规范中定义的固定格式。对于此类情况,可以如下自定义日期和时间格式:
-
Java
-
Kotlin
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
registrar.setUseIsoFormat(true);
registrar.registerFormatters(registry);
}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
override fun addFormatters(registry: FormatterRegistry) {
val registrar = DateTimeFormatterRegistrar()
registrar.setUseIsoFormat(true)
registrar.registerFormatters(registry)
}
}
请参阅 FormatterRegistrar SPI
和 FormattingConversionServiceFactoryBean 以获取有关何时使用
FormatterRegistrar 实现的更多信息。 |
验证
默认情况下,如果Bean Validation存在于类路径上(例如,Hibernate Validator),则LocalValidatorFactoryBean会被注册为全局验证器,用于@Valid和@Validated在@Controller方法参数上使用。
在你的Java配置中,你可以自定义全局Validator实例,
如下例所示:
-
Java
-
Kotlin
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public Validator getValidator() {
// ...
}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
override fun getValidator(): Validator {
// ...
}
}
请注意,您还可以在本地注册 Validator 个实现,
如下例所示:
-
Java
-
Kotlin
@Controller
public class MyController {
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.addValidators(new FooValidator());
}
}
@Controller
class MyController {
@InitBinder
protected fun initBinder(binder: WebDataBinder) {
binder.addValidators(FooValidator())
}
}
如果你需要在某个地方注入一个LocalValidatorFactoryBean,创建一个bean并用@Primary标记它,以避免与MVC配置中声明的那个发生冲突。 |
内容类型解析器
您可以配置Spring WebFlux如何从请求中确定@Controller实例的请求媒体类型。默认情况下,仅检查Accept标头,但您还可以启用基于查询参数的策略。
以下示例展示了如何自定义请求的内容类型解析:
-
Java
-
Kotlin
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public void configureContentTypeResolver(RequestedContentTypeResolverBuilder builder) {
// ...
}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
override fun configureContentTypeResolver(builder: RequestedContentTypeResolverBuilder) {
// ...
}
}
HTTP消息编解码器
以下示例展示了如何自定义请求和响应体的读取和写入方式:
-
Java
-
Kotlin
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
configurer.defaultCodecs().maxInMemorySize(512 * 1024);
}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
override fun configureHttpMessageCodecs(configurer: ServerCodecConfigurer) {
// ...
}
}
ServerCodecConfigurer 提供了一组默认的读取器和写入器。您可以使用它来添加更多的读取器和写入器,自定义默认的读取器和写入器,或完全替换默认的读取器和写入器。
对于Jackson JSON和XML,考虑使用
Jackson2ObjectMapperBuilder,
它通过以下属性自定义了Jackson的默认属性:
它还会自动注册以下知名模块,如果在类路径上检测到它们:
-
jackson-datatype-joda: 对Joda-Time类型的支持。 -
jackson-datatype-jsr310: 支持Java 8日期和时间API类型。 -
jackson-datatype-jdk8: 其他Java 8类型的支持,如Optional。 -
jackson-module-kotlin: 对Kotlin类和数据类的支持。
视图解析器
以下示例展示了如何配置视图解析:
-
Java
-
Kotlin
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
// ...
}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
override fun configureViewResolvers(registry: ViewResolverRegistry) {
// ...
}
}
The ViewResolverRegistry 为视图技术提供了快捷方式,这些技术与Spring Framework集成。以下示例使用了FreeMarker(这也需要配置底层的FreeMarker视图技术):
-
Java
-
Kotlin
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.freeMarker();
}
// Configure Freemarker...
@Bean
public FreeMarkerConfigurer freeMarkerConfigurer() {
FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
configurer.setTemplateLoaderPath("classpath:/templates");
return configurer;
}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
override fun configureViewResolvers(registry: ViewResolverRegistry) {
registry.freeMarker()
}
// Configure Freemarker...
@Bean
fun freeMarkerConfigurer() = FreeMarkerConfigurer().apply {
setTemplateLoaderPath("classpath:/templates")
}
}
您也可以插入任何ViewResolver实现,如下例所示:
-
Java
-
Kotlin
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
ViewResolver resolver = ... ;
registry.viewResolver(resolver);
}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
override fun configureViewResolvers(registry: ViewResolverRegistry) {
val resolver: ViewResolver = ...
registry.viewResolver(resolver
}
}
为了支持内容协商和通过视图解析渲染其他格式(除了HTML),你可以基于HttpMessageWriterView实现配置一个或多个默认视图,该实现接受来自spring-web的任何可用编解码器。以下示例展示了如何进行配置:
-
Java
-
Kotlin
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.freeMarker();
Jackson2JsonEncoder encoder = new Jackson2JsonEncoder();
registry.defaultViews(new HttpMessageWriterView(encoder));
}
// ...
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
override fun configureViewResolvers(registry: ViewResolverRegistry) {
registry.freeMarker()
val encoder = Jackson2JsonEncoder()
registry.defaultViews(HttpMessageWriterView(encoder))
}
// ...
}
请参阅 视图技术 了解更多关于与 Spring WebFlux 集成的视图技术。
静态资源
此选项提供了一种方便的方式来从基于Resource的列表位置提供静态资源。
在下一个示例中,给定一个以 /resources 开头的请求,相对路径用于相对于类路径上的 /static 查找并提供静态资源。资源以一年后的过期时间提供,以确保浏览器缓存的最大使用,并减少浏览器发出的 HTTP 请求。还对 Last-Modified 头进行评估,如果存在,则返回 304 状态码。下面的列表显示了示例:
-
Java
-
Kotlin
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/public", "classpath:/static/")
.setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS));
}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/public", "classpath:/static/")
.setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS))
}
}
另见 静态资源的HTTP缓存支持。
资源处理器还支持一系列的
ResourceResolver 实现和
ResourceTransformer 实现,
这些可以用来创建一个工具链,用于处理优化后的资源。
您可以使用 VersionResourceResolver 用于基于 MD5 哈希计算的版本化资源 URL,该哈希从内容、固定的应用程序版本或其他信息中计算得出。一个 ContentVersionStrategy(MD5 哈希)通常是不错的选择,但有一些显著的例外(例如与模块加载器一起使用的 JavaScript 资源)。
以下示例展示了如何在您的Java配置中使用VersionResourceResolver:
-
Java
-
Kotlin
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/public/")
.resourceChain(true)
.addResolver(new VersionResourceResolver().addContentVersionStrategy("/**"));
}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/public/")
.resourceChain(true)
.addResolver(VersionResourceResolver().addContentVersionStrategy("/**"))
}
}
您可以使用 ResourceUrlProvider 来重写URL并应用完整的解析器和转换器链(例如,插入版本)。WebFlux配置提供了一个 ResourceUrlProvider,以便它可以被注入到其他组件中。
与Spring MVC不同,目前在WebFlux中,没有办法透明地重写静态资源URL,因为没有视图技术可以利用非阻塞的解析器和转换器链。当仅提供本地资源时,解决方法是直接使用ResourceUrlProvider(例如,通过自定义元素)并阻塞。
请注意,当同时使用 EncodedResourceResolver(例如,Gzip、Brotli 编码)和 VersionedResourceResolver 时,它们必须按此顺序注册,以确保基于内容的版本始终根据未编码文件可靠地计算。
对于 WebJars,带版本的 URL 如
/webjars/jquery/1.2.0/jquery.min.js 是推荐且最有效的方法。
相关的资源位置通过 Spring Boot 默认配置(或可以通过 ResourceHandlerRegistry 手动配置),不需要添加
org.webjars:webjars-locator-core 依赖项。
无版本的URL,如/webjars/jquery/jquery.min.js,可以通过WebJarsResourceResolver支持,当org.webjars:webjars-locator-core库存在于类路径中时,会自动注册,但会增加类路径扫描,这可能会减慢应用程序的启动。解析器可以将URL重写为包含jar的版本,并且还可以匹配没有版本的传入URL — 例如,从/webjars/jquery/jquery.min.js到/webjars/jquery/1.2.0/jquery.min.js。
基于 ResourceHandlerRegistry 的 Java 配置提供了更多选项,用于细粒度控制,例如最后修改行为和优化的资源解析。 |
路径匹配
您可以自定义与路径匹配相关的选项。有关各个选项的详细信息,请参阅
PathMatchConfigurer javadoc。
以下示例展示了如何使用 PathMatchConfigurer:
-
Java
-
Kotlin
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer
.setUseCaseSensitiveMatch(true)
.addPathPrefix("/api", HandlerTypePredicate.forAnnotation(RestController.class));
}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
@Override
fun configurePathMatch(configurer: PathMatchConfigurer) {
configurer
.setUseCaseSensitiveMatch(true)
.addPathPrefix("/api", HandlerTypePredicate.forAnnotation(RestController::class.java))
}
}
|
Spring WebFlux 依赖于请求路径的解析表示,称为 Spring WebFlux 也不支持后缀模式匹配,与 Spring MVC 不同,在 Spring MVC 中我们还推荐远离对它的依赖。 |
WebSocketService
WebFlux Java配置声明了一个WebSocketHandlerAdapter bean,该bean支持WebSocket处理程序的调用。这意味着要处理WebSocket握手请求,只需通过SimpleUrlHandlerMapping将WebSocketHandler映射到URL即可。
在某些情况下,可能需要使用提供的WebSocketService服务来创建WebSocketHandlerAdapter bean,这允许配置WebSocket服务器属性。
例如:
-
Java
-
Kotlin
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public WebSocketService getWebSocketService() {
TomcatRequestUpgradeStrategy strategy = new TomcatRequestUpgradeStrategy();
strategy.setMaxSessionIdleTimeout(0L);
return new HandshakeWebSocketService(strategy);
}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
@Override
fun webSocketService(): WebSocketService {
val strategy = TomcatRequestUpgradeStrategy().apply {
setMaxSessionIdleTimeout(0L)
}
return HandshakeWebSocketService(strategy)
}
}
高级配置模式
@EnableWebFlux 个导入 DelegatingWebFluxConfiguration 如下:
-
为WebFlux应用程序提供默认的Spring配置
-
检测并委托给
WebFluxConfigurer实现以自定义该配置。
对于高级模式,你可以移除 @EnableWebFlux 并直接从 DelegatingWebFluxConfiguration 扩展,而不是实现 WebFluxConfigurer,
如下例所示:
-
Java
-
Kotlin
@Configuration
public class WebConfig extends DelegatingWebFluxConfiguration {
// ...
}
@Configuration
class WebConfig : DelegatingWebFluxConfiguration {
// ...
}
你可以保留现有的方法在WebConfig中,但现在你也可以覆盖基类中的bean声明,并且仍然可以在类路径上有任何数量的其他WebMvcConfigurer实现。