@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-компонент, хотя это было связано со своими проблемами.