此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Framework 6.2.10! |
WebFlux 配置
启用 WebFlux 配置
您可以使用@EnableWebFlux
注释,如以下示例所示:
-
Java
-
Kotlin
@Configuration
@EnableWebFlux
public class WebConfig {
}
@Configuration
@EnableWebFlux
class WebConfig
使用 Spring Boot 时,您可能需要使用@Configuration 类型WebFluxConfigurer 但没有@EnableWebFlux 以保留 Spring Boot WebFlux 自定义。有关 WebFlux 配置 API 部分和专用 Spring Boot 文档中的更多详细信息。 |
前面的示例注册了许多 Spring WebFlux 基础设施 bean 并适应依赖项在类路径上可用 — 用于 JSON、XML 等。
WebFlux 配置 API
在 Java 配置中,您可以实现WebFluxConfigurer
接口 如以下示例所示:
-
Java
-
Kotlin
@Configuration
public class WebConfig implements WebFluxConfigurer {
// Implement configuration methods...
}
@Configuration
class WebConfig : WebFluxConfigurer {
// Implement configuration methods...
}
转换、格式化
默认情况下,安装了各种数字和日期类型的格式化程序,并支持通过通过自定义@NumberFormat
,@DurationFormat
和@DateTimeFormat
在字段上和参数。
要在 Java 配置中注册自定义格式化程序和转换器,请使用以下命令:
-
Java
-
Kotlin
@Configuration
public class WebConfig implements WebFluxConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
// ...
}
}
@Configuration
class WebConfig : WebFluxConfigurer {
override fun addFormatters(registry: FormatterRegistry) {
// ...
}
}
默认情况下,Spring WebFlux 在解析和格式化日期时会考虑请求 Locale 值。 这适用于日期表示为带有“输入”形式的字符串的表单 领域。 但是,对于“日期”和“时间”表单字段,浏览器使用定义的固定格式在 HTML 规范中。对于这种情况,可以按如下方式自定义日期和时间格式:
-
Java
-
Kotlin
@Configuration
public class WebConfig implements WebFluxConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
registrar.setUseIsoFormat(true);
registrar.registerFormatters(registry);
}
}
@Configuration
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
method 参数。
在 Java 配置中,您可以自定义全局Validator
实例 如以下示例所示:
-
Java
-
Kotlin
@Configuration
public class WebConfig implements WebFluxConfigurer {
@Override
public Validator getValidator() {
// ...
}
}
@Configuration
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
public class WebConfig implements WebFluxConfigurer {
@Override
public void configureContentTypeResolver(RequestedContentTypeResolverBuilder builder) {
// ...
}
}
@Configuration
class WebConfig : WebFluxConfigurer {
override fun configureContentTypeResolver(builder: RequestedContentTypeResolverBuilder) {
// ...
}
}
HTTP 消息编解码器
以下示例演示如何自定义请求和响应正文的读取和写入方式:
-
Java
-
Kotlin
@Configuration
public class WebConfig implements WebFluxConfigurer {
@Override
public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
configurer.defaultCodecs().maxInMemorySize(512 * 1024);
}
}
@Configuration
class WebConfig : WebFluxConfigurer {
override fun configureHttpMessageCodecs(configurer: ServerCodecConfigurer) {
configurer.defaultCodecs().maxInMemorySize(512 * 1024)
}
}
ServerCodecConfigurer
提供了一组默认的读取器和写入器。您可以使用它来添加
更多的读写器,自定义默认的,或完全替换默认的。
对于 Jackson JSON 和 XML,请考虑使用Jackson2ObjectMapperBuilder
,
它使用以下属性自定义 Jackson 的默认属性:
如果在类路径上检测到以下已知模块,它还会自动注册它们:
-
jackson-datatype-jsr310
:支持 Java 8 日期和时间 API 类型。 -
jackson-datatype-jdk8
:支持其他 Java 8 类型,例如Optional
. -
jackson-module-kotlin
:支持 Kotlin 类和数据类。
查看解析器
以下示例演示如何配置视图分辨率:
-
Java
-
Kotlin
@Configuration
public class WebConfig implements WebFluxConfigurer {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
// ...
}
}
@Configuration
class WebConfig : WebFluxConfigurer {
override fun configureViewResolvers(registry: ViewResolverRegistry) {
// ...
}
}
这ViewResolverRegistry
具有 Spring Framework 使用的视图技术的快捷方式
集成。以下示例使用 FreeMarker(这也需要配置
底层 FreeMarker 视图技术):
-
Java
-
Kotlin
@Configuration
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
class WebConfig : WebFluxConfigurer {
override fun configureViewResolvers(registry: ViewResolverRegistry) {
registry.freeMarker()
}
// Configure Freemarker...
@Bean
fun freeMarkerConfigurer() = FreeMarkerConfigurer().apply {
setTemplateLoaderPath("classpath:/templates")
}
}
您还可以插入任何ViewResolver
实现,如以下示例所示:
-
Java
-
Kotlin
@Configuration
public class WebConfig implements WebFluxConfigurer {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
ViewResolver resolver = ... ;
registry.viewResolver(resolver);
}
}
@Configuration
class WebConfig : WebFluxConfigurer {
override fun configureViewResolvers(registry: ViewResolverRegistry) {
val resolver: ViewResolver = ...
registry.viewResolver(resolver
}
}
-
Java
-
Kotlin
@Configuration
public class WebConfig implements WebFluxConfigurer {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.freeMarker();
Jackson2JsonEncoder encoder = new Jackson2JsonEncoder();
registry.defaultViews(new HttpMessageWriterView(encoder));
}
// ...
}
@Configuration
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
header 也是
评估,如果存在,则304
状态代码。以下列表显示
示例:
-
Java
-
Kotlin
@Configuration
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
class WebConfig : WebFluxConfigurer {
override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/public", "classpath:/static/")
.setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS))
}
}
另请参阅对静态资源的 HTTP 缓存支持。
资源处理程序还支持ResourceResolver
implementations 和ResourceTransformer
实现
可用于创建用于处理优化资源的工具链。
您可以使用VersionResourceResolver
对于基于 MD5 哈希的版本化资源 URL
根据内容、固定应用程序版本或其他信息计算。一个ContentVersionStrategy
(MD5 哈希)是一个不错的选择,但有一些值得注意的例外(例如
与模块加载器一起使用的 JavaScript 资源)。
以下示例演示如何使用VersionResourceResolver
在您的 Java 配置中:
-
Java
-
Kotlin
@Configuration
public class WebConfig implements WebFluxConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/public/")
.resourceChain(true)
.addResolver(new VersionResourceResolver().addContentVersionStrategy("/**"));
}
}
@Configuration
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
Dependency。
无版本 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 提供更多选项
用于细粒度控制,例如,上次修改的行为和优化的资源解析。 |
路径匹配
您可以自定义与路径匹配相关的选项。有关各个选项的详细信息,请参阅PathMatchConfigurer
javadoc 的文档。
以下示例演示如何使用PathMatchConfigurer
:
-
Java
-
Kotlin
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.method.HandlerTypePredicate;
import org.springframework.web.reactive.config.PathMatchConfigurer;
import org.springframework.web.reactive.config.WebFluxConfigurer;
@Configuration
public class WebConfig implements WebFluxConfigurer {
@Override
public void configurePathMatching(PathMatchConfigurer configurer) {
configurer.addPathPrefix(
"/api", HandlerTypePredicate.forAnnotation(RestController.class));
}
}
import org.springframework.context.annotation.Configuration
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.method.HandlerTypePredicate
import org.springframework.web.reactive.config.PathMatchConfigurer
import org.springframework.web.reactive.config.WebFluxConfigurer
@Configuration
class WebConfig : WebFluxConfigurer {
override fun configurePathMatching(configurer: PathMatchConfigurer) {
configurer.addPathPrefix(
"/api", HandlerTypePredicate.forAnnotation(RestController::class.java))
}
}
Spring WebFlux 依赖于名为 Spring WebFlux 也不支持后缀模式匹配,这与 Spring MVC 不同,在 Spring MVC 中,我们 也建议远离 依赖它。 |
阻止执行
WebFlux Java 配置允许您在 WebFlux 中自定义阻塞执行。
您可以通过提供
一AsyncTaskExecutor
例如VirtualThreadTaskExecutor
如下:
-
Java
-
Kotlin
@Configuration
public class WebConfig implements WebFluxConfigurer {
@Override
public void configureBlockingExecution(BlockingExecutionConfigurer configurer) {
AsyncTaskExecutor executor = ...
configurer.setExecutor(executor);
}
}
@Configuration
class WebConfig : WebFluxConfigurer {
@Override
fun configureBlockingExecution(configurer: BlockingExecutionConfigurer) {
val executor = ...
configurer.setExecutor(executor)
}
}
默认情况下,返回类型的控制器方法不被配置的ReactiveAdapterRegistry
被视为阻塞,但您可以设置自定义控制器
方法谓词通过BlockingExecutionConfigurer
.
WebSocket服务
WebFlux Java 配置声明了WebSocketHandlerAdapter
bean 提供
支持调用 WebSocket 处理程序。这意味着剩下的所有事情要做
处理 WebSocket 握手请求的顺序是将WebSocketHandler
到 URL
通过SimpleUrlHandlerMapping
.
在某些情况下,可能需要创建WebSocketHandlerAdapter
bean 与
提供WebSocketService
允许配置 WebSocket 服务器属性的服务。
例如:
-
Java
-
Kotlin
@Configuration
public class WebConfig implements WebFluxConfigurer {
@Override
public WebSocketService getWebSocketService() {
TomcatRequestUpgradeStrategy strategy = new TomcatRequestUpgradeStrategy();
strategy.setMaxSessionIdleTimeout(0L);
return new HandshakeWebSocketService(strategy);
}
}
@Configuration
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
实现
类路径。