java - 设置 WebClient.Builder.exchangeStrategies() 而不丢失 Spring Jackson 配置

标签 java spring-boot jackson spring-webflux

我使用以下代码(来自 this answer )来配置要记录到 WebClient 请求的 header :

ExchangeStrategies exchangeStrategies = ExchangeStrategies.withDefaults();
exchangeStrategies
    .messageWriters().stream()
    .filter(LoggingCodecSupport.class::isInstance)
    .forEach(writer -> ((LoggingCodecSupport)writer).setEnableLoggingRequestDetails(true));

client = WebClient.builder()
    .exchangeStrategies(exchangeStrategies)

这有效,但会导致我的 jackson 配置丢失。在我的 application.properties 中我有:

spring.jackson.default-property-inclusion=non-null
spring.jackson.deserialization.accept-empty-string-as-null-object=true

被上面的代码覆盖。这是我的解决方法:

  @Autowired ObjectMapper objectMapper;

  @Bean
  WebClientCustomizer webClientCustomizer() {
    return (WebClient.Builder builder) -> {
      builder
          .exchangeStrategies(createExchangeStrategiesWhichLogHeaders())
    };
  }

  private ExchangeStrategies createExchangeStrategiesWhichLogHeaders() {
    ExchangeStrategies exchangeStrategies =
        ExchangeStrategies.builder()
            .codecs(
                clientDefaultCodecsConfigurer -> {
                  clientDefaultCodecsConfigurer
                      .defaultCodecs()
                      .jackson2JsonEncoder(
                          new Jackson2JsonEncoder(objectMapper, MediaType.APPLICATION_JSON));
                  clientDefaultCodecsConfigurer
                      .defaultCodecs()
                      .jackson2JsonDecoder(
                          new Jackson2JsonDecoder(objectMapper, MediaType.APPLICATION_JSON));
                })
            .build();

    exchangeStrategies
        .messageWriters()
        .stream()
        .filter(LoggingCodecSupport.class::isInstance)
        .forEach(writer -> ((LoggingCodecSupport) writer).setEnableLoggingRequestDetails(true));

    return exchangeStrategies;
  }

这可行,但感觉有点奇怪。问题是:我是否需要像这样包含 jackson/objectMapper 配置,或者是否有更简单的方法来避免 Spring objectMapper 配置被覆盖?

最佳答案

从 Spring Boot 2.1.0 开始,您可以通过启用以下属性来实现此目的:

spring.http.log-request-details=true

如果您使用的是以前的 Spring Boot 版本,您应该能够自定义它,而无需覆盖或重建整个配置,如下所示:

@Configuration
static class LoggingCodecConfig {

    @Bean
    @Order(0)
    public CodecCustomizer loggingCodecCustomizer() {
        return (configurer) -> configurer.defaultCodecs()
                .enableLoggingRequestDetails(true);
    }

}

关于java - 设置 WebClient.Builder.exchangeStrategies() 而不丢失 Spring Jackson 配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53444547/

相关文章:

java - 来自 MongoDB BSON 的 Jackson ObjectMapper

java - 如何使用java管理Excel文件中的Excel工作表而不使用第三方库

java - 如何在 ArrayList 内的对象内创建日历对象

java - 使用 Java 流对内部映射进行分组

java - 可以在 HttpServletResponse.sendRedirect() 中发送隐藏参数吗?

generics - 使用通用函数不适用于使用 jackson 加载 YAML 列表

java - 在 Main 中调用字符串方法

spring - 预检响应具有无效的 HTTP 状态代码 403 + angular 2 + Java Spring boot

java - 如何在 Spring Boot 中以编程方式创建 bean?

java - JsonFormat$Value.hasLenient() 休息调用时出错