首页 > 解决方案 > WebFluxConfigurer 上的 @EnableWebFlux 会按预期自动配置 ThymeleafViewResolver

问题描述

我正在构建一个从 spring-boot-starter-webflux 开始的 REST api,但我也希望该应用程序使用 webjar 提供一个招摇的 UI。我需要调整 swagger UI 的初始化方式,所以我制作了一个 @Controller,它返回一个 Mono 来触发渲染视图。REST api 还需要一个自定义的 jackson ObjectMapper 并启用蛇案例命名策略等。

Spring Boot Docs说要实现这一点,我应该提供一个扩展 WebFluxConfigurer 的 @Configuration 类,但我应该关闭 @EnableWebflux。这是我到目前为止所拥有的(Kotlin):

配置

@Configuration
@ComponentScan
class CommonConfig : WebFluxConfigurer {

    override fun configureHttpMessageCodecs(configurer: ServerCodecConfigurer) {
        configurer.defaultCodecs().jackson2JsonDecoder(
                Jackson2JsonDecoder(objectMapper())
        )
        configurer.defaultCodecs().jackson2JsonEncoder(
                Jackson2JsonEncoder(objectMapper())
        )
    }

    private fun objectMapper() = Jackson2ObjectMapperBuilder
            .json()
            .propertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE)
            .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
            .build<ObjectMapper>().also {
                it.configOverride(BigDecimal::class.java).format = JsonFormat.Value.forShape(JsonFormat.Shape.STRING)
            }
}

控制器

@Controller
class SwaggerController(
        val swaggerConfig: SwaggerConfig
) {
    @GetMapping("/swagger-ui")
    fun swagger(model: Model): Mono<String> {

        model.addAttribute("docUrl", swaggerConfig.docUrl)
        return Mono.just("swagger-ui")
    }
}

使用此配置,swagger 视图渲染得很好,但是当我尝试发布到我的一个 api 端点时,它抱怨缺少必需的属性(通过发送带有骆驼案例而不是我想要的蛇案例的数据来解决)。如果我将@EnableWebFlux 添加到我的CommonConfig 类,自定义对象映射器会被拾取并且我可以发送蛇案例数据,但随后不会呈现swagger 视图。我得到:

java.lang.IllegalStateException: Could not resolve view with name 'swagger-ui'.
    at org.springframework.web.reactive.result.view.ViewResolutionResultHandler.lambda$resolveViews$3(ViewResolutionResultHandler.java:278) ~[spring-webflux-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:

这大概是因为没有注册thymeleaf ViewResolver。

文档确实说如果我想“完全控制 Spring WebFlux,您可以添加自己的带有 @EnableWebFlux 注释的 @Configuration”,这解释了为什么没有 ViewResolver。但这不是我想要的。我想要大部分的 webflux 自动配置,但我想提供我自己定制的 ObjectMapper。这样做的正确方法是什么?

标签: spring-bootspring-webfluxspring-kotlin

解决方案


我最终 1) 切换到 FreeMarker 和 2) 需要将我的自定义 ObjectMapper 公开为 bean,尽管这有其自身的问题。


推荐阅读