0
点赞
收藏
分享

微信扫一扫

Spring WebFlux框架 - WebFlux 配置

彪悍的鼹鼠 2022-01-10 阅读 73

接上一篇博客:https://blog.csdn.net/qq_43605444/article/details/122420890?spm=1001.2014.3001.5502

11、WebFlux 配置

WebFlux Java 配置声明了使用带注解的控制器或功能端点处理请求所需的组件,并提供了一个 API 来自定义配置。 这意味着您不需要了解 Java 配置创建的底层 bean。 但是,如果您想了解它们,可以在 WebFluxConfigurationSupport 中查看它们或在特殊 Bean 类型中阅读更多关于它们的信息。

对于配置 API 中不可用的更高级自定义,您可以通过高级配置模式获得对配置的完全控制。

11.1 启用 WebFlux 配置

您可以在 Java 配置中使用 @EnableWebFlux 注解,如以下示例所示:

@Configuration
@EnableWebFlux
public class WebConfig {
}

前面的示例注册了许多 Spring WebFlux 基础设施 bean,并适应类路径上可用的依赖项 — 对于 JSON、XML 等。

11.2 WebFlux 配置 API

在您的 Java 配置中,您可以实现 WebFluxConfigurer 接口,如以下示例所示:

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

    // Implement configuration methods...
}

11.3 Conversion, formatting

默认情况下,安装了各种数字和日期类型的格式化程序,并支持通过字段上的 @NumberFormat@DateTimeFormat 进行自定义。

要在 Java 配置中注册自定义格式化程序和转换器,请使用以下命令:

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        // ...
    }

}

默认情况下,Spring WebFlux 在解析和格式化日期值时会考虑请求区域设置。 这适用于日期表示为带有“输入”表单字段的字符串的表单。 然而,对于“日期”和“时间”表单字段,浏览器使用 HTML 规范中定义的固定格式。 对于这种情况,可以按如下方式自定义日期和时间格式:

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
        registrar.setUseIsoFormat(true);
        registrar.registerFormatters(registry);
    }
}

11.4 验证

默认情况下,如果类路径中存在 Bean Validation(例如,Hibernate Validator),则 LocalValidatorFactoryBean 将注册为全局验证器,以便在 @Controller 方法参数上与 @Valid@Validated 一起使用。

在您的 Java 配置中,您可以自定义全局 Validator 实例,如以下示例所示:

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

    @Override
    public Validator getValidator(); {
        // ...
    }

}

请注意,您还可以在本地注册 Validator 实现,如以下示例所示:

@Controller
public class MyController {

    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.addValidators(new FooValidator());
    }

}

11.5 内容类型解析

您可以配置 Spring WebFlux 如何从请求中确定 @Controller 实例的请求媒体类型。 默认情况下,仅选中 Accept 标头,但您也可以启用基于查询参数的策略。

以下示例显示了如何自定义请求的内容类型解析:

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

    @Override
    public void configureContentTypeResolver(RequestedContentTypeResolverBuilder builder) {
        // ...
    }
}

11.6 HTTP 消息编解码器

以下示例显示了如何自定义请求和响应正文的读取和写入方式:

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

    @Override
    public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
        configurer.defaultCodecs().maxInMemorySize(512 * 1024);
    }
}

ServerCodecConfigurer 提供了一组默认的读取器和写入器。 您可以使用它来添加更多的 readers 和 writers,自定义默认的,或者完全替换默认的。

对于 Jackson JSON 和 XML,请考虑使用 Jackson2ObjectMapperBuilder,它使用以下属性自定义 Jackson 的默认属性:

  • DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES 被禁用。
  • MapperFeature.DEFAULT_VIEW_INCLUSION 被禁用。

如果在类路径中检测到以下知名模块,它还会自动注册它们:

  • jackson-datatype-joda:支持 Joda-Time 类型。
  • jackson-datatype-jsr310:支持 Java 8 日期和时间 API 类型。
  • jackson-datatype-jdk8:支持其他 Java 8 类型,例如 Optional。
  • jackson-module-kotlin:支持 Kotlin 类和数据类。

11.7 视图解析器

以下示例显示了如何配置视图解析器:

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        // ...
    }
}

ViewResolverRegistry 具有与 Spring 框架集成的视图技术的快捷方式。 以下示例使用 FreeMarker(也需要配置底层 FreeMarker 视图技术):

@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;
    }
}

您还可以插入任何 ViewResolver 实现,如以下示例所示:

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {


    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        ViewResolver resolver = ... ;
        registry.viewResolver(resolver);
    }
}

要支持内容协商和通过视图解析(除了 HTML)呈现其他格式,您可以基于 HttpMessageWriterView 实现配置一个或多个默认视图,该实现接受来自 spring-web 的任何可用编解码器。 以下示例显示了如何执行此操作:

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {


    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.freeMarker();

        Jackson2JsonEncoder encoder = new Jackson2JsonEncoder();
        registry.defaultViews(new HttpMessageWriterView(encoder));
    }

    // ...
}

有关与 Spring WebFlux 集成的视图技术的更多信息,请参阅视图技术。

11.8 静态资源

此选项提供了一种从基于资源的位置列表中提供静态资源的便捷方式。

在下一个示例中,给定以 /resources 开头的请求,相对路径用于在类路径上查找和提供相对于 /static 的静态资源。 资源的服务期限为一年,以确保最大限度地使用浏览器缓存并减少浏览器发出的 HTTP 请求。 Last-Modified 标头也被评估,如果存在,则返回 304 状态代码。 以下列表显示了示例:

@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));
    }

}

资源处理程序还支持一系列 ResourceResolver 实现和 ResourceTransformer 实现,可用于创建用于处理优化资源的工具链。

您可以将 VersionResourceResolver 用于基于从内容、固定应用程序版本或其他信息计算的 MD5 哈希值的版本化资源 URL。 ContentVersionStrategy(MD5 哈希)是一个不错的选择,但有一些明显的例外(例如与模块加载器一起使用的 JavaScript 资源)。

以下示例显示了如何在 Java 配置中使用 VersionResourceResolver

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**")
                .addResourceLocations("/public/")
                .resourceChain(true)
                .addResolver(new VersionResourceResolver().addContentVersionStrategy("/**"));
    }

}

您可以使用 ResourceUrlProvider 重写 URL 并应用完整的解析器和转换器链(例如,插入版本)。 WebFlux 配置提供了一个 ResourceUrlProvider 以便可以将其注入其他人。

与 Spring MVC 不同,目前在 WebFlux 中,没有办法透明地重写静态资源 URL,因为没有视图技术可以利用解析器和转换器的非阻塞链。 仅提供本地资源时,解决方法是直接使用 ResourceUrlProvider(例如,通过自定义元素)并阻止。

请注意,当同时使用 EncodedResourceResolver(例如,Gzip、Brotli 编码)和 VersionedResourceResolver 时,必须按此顺序注册它们,以确保始终基于未编码文件可靠地计算基于内容的版本。

WebJars 也通过 WebJarsResourceResolver 支持,当 org.webjars:webjars-locator-core 库出现在类路径上时,它会自动注册。 解析器可以重写 URL 以包含 jar 的版本,也可以匹配没有版本的传入 URL — 例如,从 /jquery/jquery.min.js/jquery/1.2.0/jquery.min.js

11.9 路径匹配

您可以自定义与路径匹配相关的选项。 有关各个选项的详细信息,请参阅 PathMatchConfigurer javadoc。 以下示例显示了如何使用 PathMatchConfigurer

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        configurer
            .setUseCaseSensitiveMatch(true)
            .setUseTrailingSlashMatch(false)
            .addPathPrefix("/api",
                    HandlerTypePredicate.forAnnotation(RestController.class));
    }
}

11.10 WebSocketService

WebFlux Java 配置声明了一个 WebSocketHandlerAdapter bean,它为 WebSocket 处理程序的调用提供支持。 这意味着为了处理 WebSocket 握手请求,剩下要做的就是通过 SimpleUrlHandlerMappingWebSocketHandler 映射到 URL。

在某些情况下,可能需要使用提供的 WebSocketService 服务创建 WebSocketHandlerAdapter bean,该服务允许配置 WebSocket 服务器属性。 例如:

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

    @Override
    public WebSocketService getWebSocketService() {
        TomcatRequestUpgradeStrategy strategy = new TomcatRequestUpgradeStrategy();
        strategy.setMaxSessionIdleTimeout(0L);
        return new HandshakeWebSocketService(strategy);
    }
}

11.11 高级配置模式

@EnableWebFlux 导入 DelegatingWebFluxConfiguration

  • 为 WebFlux 应用程序提供默认 Spring 配置
  • 检测并委托给 WebFluxConfigurer 实现以自定义该配置。

对于高级模式,您可以删除 @EnableWebFlux 并直接从 DelegatingWebFluxConfiguration 扩展,而不是实现 WebFluxConfigurer,如以下示例所示:

@Configuration
public class WebConfig extends DelegatingWebFluxConfiguration {

    // ...
}

您可以在 Web Config 中保留现有方法,但您现在也可以覆盖基类中的 bean 声明,并且在类路径上仍然有任意数量的其他 WebMvcConfigurer 实现。

举报

相关推荐

0 条评论