@EnableWebFlux в WebFluxConfigurer выполняет автоматическую настройку ThymeleafViewResolver, как ожидалось

Я создаю REST api, начиная с spring-boot-starter-webflux, но я также хотел бы, чтобы приложение обслуживало пользовательский интерфейс Swagger с использованием веб-файла. Мне нужно настроить инициализацию пользовательского интерфейса Swagger, поэтому я создал @Controller, который возвращает Mono для запуска рендеринга представления. Для REST api также требуется настраиваемый объект Jackson ObjectMapper с включенной стратегией именования snake case, среди прочего.

В Spring Boot Docs говорится, что для этого я должен предоставить класс @Configuration, расширяющий WebFluxConfigurer, но я должен оставить @EnableWebflux выключенным. Вот что у меня есть (Котлин):

Конфиг

@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:

Предположительно, это связано с тем, что ViewResolver не зарегистрирован.

В документации действительно говорится, что если я хочу "получить полный контроль над Spring WebFlux, вы можете добавить свою собственную @Configuration, аннотированную @EnableWebFlux", что объясняет, почему нет ViewResolver. Но я не этого хочу. Мне нужна большая часть автоконфигурации webflux, но я хочу предоставить свой собственный настраиваемый ObjectMapper. Как правильно это сделать?

1 ответ

Решение

Я закончил тем, что 1) переключился на FreeMarker и 2) мне нужно было выставить мой пользовательский ObjectMapper как bean-компонент, хотя это было связано со своими проблемами.

Другие вопросы по тегам