Spring Boot自动配置的Jackson ObjectMapper默认情况下不会用于WebFlux WebClient

3
在我的Spring Boot应用程序中,我使用响应式WebFlux WebClient从SSE(Server-Sent Events)端点检索流式JSON数据。根据官方文档的建议,通过在Spring Boot中设置配置选项(如spring.jackson.deserialization.read-date-timestamps-as-nanoseconds=false),修改默认自动配置的Jackson ObjectMapper行为对WebFlux WebClient没有影响。我还尝试了这个SO线程中概述的其他建议,例如为WebFlux配置创建自定义bean,但它们没有帮助,配置仍未被拾取。请注意,HTML标记已保留。
3个回答

2

经过大量时间调试Spring WebFlux / Jackson库代码,我终于在查看响应式WebFlux WebClient文档时找到了解决问题的提示 (文档链接)。需要进行一些定制操作来使WebClient使用默认自动配置的Jackson ObjectMapper。解决方案是,在创建WebClient新实例时配置用于处理服务器发送事件的默认解码器。以下是示例代码:

@Component
public class MarketDataFetcher implements CommandLineRunner {

    // ...

    private final WebClient webClient;

    public MarketDataFetcher(ObjectMapper objectMapper) {
        webClient = createWebClient(objectMapper);
    }

    private WebClient createWebClient(ObjectMapper objectMapper) {
        return WebClient.builder()
                .codecs(configurer -> configurer.defaultCodecs()
                        .serverSentEventDecoder(new Jackson2JsonDecoder(objectMapper)))
                .baseUrl(BASE_URL)
                .build();
    }
}

ObjectMapper会被Spring自动注入,因此不需要使用@Autowired注释。

如果官方文档能更加明确地表述这一点,那肯定会有所帮助。希望这个答案对于面临类似问题的人有所帮助!


1
类似的问题已经在这个问题上提出过 -> https://dev59.com/MFcP5IYBdhLWcg3w19Xz - Nipuna Saranga

0
我在Spring Boot docs中发现:

客户端实例是使用由Spring Boot自动配置的WebClient.Builder bean构建的

还有专门讨论WebClient定制的部分,它说:

为了使任何定制的范围尽可能狭窄,注入自动配置的WebClient.Builder,然后根据需要调用其方法。

因此,使用已配置的ObjectMapper的最简单方法是像这样定义WebClient bean:
@Bean
public WebClient webClient(WebClient.Builder builder) {
    return builder.build();
}

这真的很不方便,Spring Boot默认情况下不会自动完成这个操作,考虑到其他许多功能都已经配置好可以直接使用,但是相比手动配置编解码器来说,还是要好得多。

0
我还没有尝试过问题中提到的高级属性设置,但是你可以通过使用Jackson2ObjectMapperBuilderCustomizer在应用程序级别上对Jackson的ObjectMapper进行精确配置,就像我在我的另一个回答中解释的那样。
@Configuration
public class MyAppConfiguration {

  @Bean
  public Jackson2ObjectMapperBuilderCustomizer jacksonJsonCustomizer() {
    return builder -> builder.modulesToInstall(/*TODO specify modules here);
  }

}

在有限的测试中,WebFlux似乎使用这个配置,例如使用.bodyToMono(SomeType.class)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接