From 26a2d3875f89cce1f2ba08bc58d4646ec7d83667 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Thu, 12 Dec 2019 20:56:03 +0000 Subject: [PATCH] Expose ClientCodecConfigurer in WebClient.Builder Using Consumer instead of Consumer eliminates one level of nesting that is also unnecessary since codecs are the only strategy at present. Backport of dd9b6287b4c3b507f963c655144ed06dd8f5ff21 Closes gh-24201 --- .../server/DefaultWebTestClientBuilder.java | 8 ++++++ .../web/reactive/server/WebTestClient.java | 24 ++++++++++++----- .../client/DefaultWebClientBuilder.java | 11 ++++++++ .../reactive/function/client/WebClient.java | 27 +++++++++++++------ src/docs/asciidoc/web/webflux.adoc | 14 ++++------ 5 files changed, 60 insertions(+), 24 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClientBuilder.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClientBuilder.java index 82006d37b25..69279499fe7 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClientBuilder.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClientBuilder.java @@ -23,6 +23,7 @@ import java.util.function.Consumer; import org.springframework.http.HttpHeaders; import org.springframework.http.client.reactive.ClientHttpConnector; import org.springframework.http.client.reactive.ReactorClientHttpConnector; +import org.springframework.http.codec.ClientCodecConfigurer; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.MultiValueMap; @@ -136,12 +137,19 @@ class DefaultWebTestClientBuilder implements WebTestClient.Builder { return this; } + @Override + public WebTestClient.Builder codecs(Consumer configurer) { + this.webClientBuilder.codecs(configurer); + return this; + } + @Override public WebTestClient.Builder exchangeStrategies(ExchangeStrategies strategies) { this.webClientBuilder.exchangeStrategies(strategies); return this; } + @SuppressWarnings("deprecation") @Override public WebTestClient.Builder exchangeStrategies(Consumer configurer) { this.webClientBuilder.exchangeStrategies(configurer); diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java index e8b109cbc01..691d7aa6846 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java @@ -36,6 +36,7 @@ import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; import org.springframework.http.client.reactive.ClientHttpConnector; import org.springframework.http.client.reactive.ClientHttpRequest; +import org.springframework.http.codec.ClientCodecConfigurer; import org.springframework.http.codec.ServerCodecConfigurer; import org.springframework.lang.Nullable; import org.springframework.util.MultiValueMap; @@ -435,14 +436,22 @@ public interface WebTestClient { */ Builder filters(Consumer> filtersConsumer); + /** + * Configure the codecs for the {@code WebClient} in the + * {@link #exchangeStrategies(ExchangeStrategies) underlying} + * {@code ExchangeStrategies}. + * @param configurer the configurer to apply + * @since 5.1.13 + */ + Builder codecs(Consumer configurer); + /** * Configure the {@link ExchangeStrategies} to use. - *

Note that in a scenario where the builder is configured by - * multiple parties, it is preferable to use - * {@link #exchangeStrategies(Consumer)} in order to customize the same - * {@code ExchangeStrategies}. This method here sets the strategies that - * everyone else then can customize. - *

By default this is {@link ExchangeStrategies#withDefaults()}. + *

For most cases, prefer using {@link #codecs(Consumer)} which allows + * customizing the codecs in the {@code ExchangeStrategies} rather than + * replace them. That ensures multiple parties can contribute to codecs + * configuration. + *

By default this is set to {@link ExchangeStrategies#withDefaults()}. * @param strategies the strategies to use */ Builder exchangeStrategies(ExchangeStrategies strategies); @@ -452,8 +461,9 @@ public interface WebTestClient { * {@link #exchangeStrategies(ExchangeStrategies)}. This method is * designed for use in scenarios where multiple parties wish to update * the {@code ExchangeStrategies}. - * @since 5.1.12 + * @deprecated as of 5.1.13 in favor of {@link #codecs(Consumer)} */ + @Deprecated Builder exchangeStrategies(Consumer configurer); /** diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClientBuilder.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClientBuilder.java index 44c3164b701..c255c439d32 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClientBuilder.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClientBuilder.java @@ -27,6 +27,7 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.client.reactive.ClientHttpConnector; import org.springframework.http.client.reactive.JettyClientHttpConnector; import org.springframework.http.client.reactive.ReactorClientHttpConnector; +import org.springframework.http.codec.ClientCodecConfigurer; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -206,12 +207,22 @@ final class DefaultWebClientBuilder implements WebClient.Builder { return this; } + @Override + public WebClient.Builder codecs(Consumer configurer) { + if (this.strategiesConfigurers == null) { + this.strategiesConfigurers = new ArrayList<>(4); + } + this.strategiesConfigurers.add(builder -> builder.codecs(configurer)); + return this; + } + @Override public WebClient.Builder exchangeStrategies(ExchangeStrategies strategies) { this.strategies = strategies; return this; } + @SuppressWarnings("deprecation") @Override public WebClient.Builder exchangeStrategies(Consumer configurer) { if (this.strategiesConfigurers == null) { diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClient.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClient.java index f60a822597c..eda41805c75 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClient.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClient.java @@ -37,6 +37,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.client.reactive.ClientHttpConnector; import org.springframework.http.client.reactive.ClientHttpRequest; +import org.springframework.http.codec.ClientCodecConfigurer; import org.springframework.util.MultiValueMap; import org.springframework.web.reactive.function.BodyInserter; import org.springframework.web.reactive.function.BodyInserters; @@ -288,14 +289,22 @@ public interface WebClient { */ Builder clientConnector(ClientHttpConnector connector); + /** + * Configure the codecs for the {@code WebClient} in the + * {@link #exchangeStrategies(ExchangeStrategies) underlying} + * {@code ExchangeStrategies}. + * @param configurer the configurer to apply + * @since 5.1.13 + */ + Builder codecs(Consumer configurer); + /** * Configure the {@link ExchangeStrategies} to use. - *

Note that in a scenario where the builder is configured by - * multiple parties, it is preferable to use - * {@link #exchangeStrategies(Consumer)} in order to customize the same - * {@code ExchangeStrategies}. This method here sets the strategies that - * everyone else then can customize. - *

By default this is {@link ExchangeStrategies#withDefaults()}. + *

For most cases, prefer using {@link #codecs(Consumer)} which allows + * customizing the codecs in the {@code ExchangeStrategies} rather than + * replace them. That ensures multiple parties can contribute to codecs + * configuration. + *

By default this is set to {@link ExchangeStrategies#withDefaults()}. * @param strategies the strategies to use */ Builder exchangeStrategies(ExchangeStrategies strategies); @@ -305,15 +314,17 @@ public interface WebClient { * {@link #exchangeStrategies(ExchangeStrategies)}. This method is * designed for use in scenarios where multiple parties wish to update * the {@code ExchangeStrategies}. - * @since 5.1.12 + * @deprecated as of 5.1.13 in favor of {@link #codecs(Consumer)} */ + @Deprecated Builder exchangeStrategies(Consumer configurer); /** * Provide an {@link ExchangeFunction} pre-configured with * {@link ClientHttpConnector} and {@link ExchangeStrategies}. *

This is an alternative to, and effectively overrides - * {@link #clientConnector}, and {@link #exchangeStrategies}. + * {@link #clientConnector}, and + * {@link #exchangeStrategies(ExchangeStrategies)}. * @param exchangeFunction the exchange function to use */ Builder exchangeFunction(ExchangeFunction exchangeFunction); diff --git a/src/docs/asciidoc/web/webflux.adoc b/src/docs/asciidoc/web/webflux.adoc index 3b0e41a055b..3d047c642b7 100644 --- a/src/docs/asciidoc/web/webflux.adoc +++ b/src/docs/asciidoc/web/webflux.adoc @@ -908,20 +908,16 @@ The following example shows how to do so for client-side requests: [source,java,indent=0] [subs="verbatim,quotes"] ---- - Consumer consumer = configurer -> { - CustomDecoder customDecoder = new CustomDecoder(); - configurer.customCodecs().decoder(customDecoder); - configurer.customCodecs().withDefaultCodecConfig(config -> - customDecoder.maxInMemorySize(config.maxInMemorySize()) - ); - } - WebClient webClient = WebClient.builder() - .exchangeStrategies(strategies -> strategies.codecs(consumer)) + .codecs(configurer -> { + CustomDecoder decoder = new CustomDecoder(); + configurer.customCodecs().registerWithDefaultConfig(decoder); + }) .build(); ---- ==== + [[webflux-dispatcher-handler]] == `DispatcherHandler` [.small]#<>#