Allow ExchangeStrategies customizations in WebClient
Prior to this commit, developers could configure their WebClient to use their custom `ExchangeStrategies`, by providing it in the `WebClient.Builder` chain. Once created, an `ExchangeStrategies` instance is not mutable, which makes it hard for further customizations by other components. In the case of the reported issue, other components would override the default configuration for the codecs maxInMemorySize. This commit makes the `ExchangeStrategies` mutable and uses that fact to further customize them with a new `WebClient.Builder#exchangeStrategies` `Consumer` variant. This commit is also deprecating those mutating variants in favor of a new `WebClient.Builder#exchangeStrategies` that takes a `ExchangeStrategies#Builder` directly and avoids mutation issues altogether. Closes gh-23961
This commit is contained in:
@@ -41,28 +41,26 @@ The following example configures <<web-reactive.adoc#webflux-codecs, HTTP codecs
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
ExchangeStrategies strategies = ExchangeStrategies.builder()
|
||||
.codecs(configurer -> {
|
||||
// ...
|
||||
})
|
||||
.build();
|
||||
Consumer<ExchangeStrategies.Builder> customizeCodecs = builder -> {
|
||||
builder.codecs(configurer -> {
|
||||
//...
|
||||
});
|
||||
};
|
||||
|
||||
WebClient client = WebClient.builder()
|
||||
.exchangeStrategies(strategies)
|
||||
.exchangeStrategies(customizeCodecs)
|
||||
.build();
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
val strategies = ExchangeStrategies.builder()
|
||||
.codecs {
|
||||
// ...
|
||||
val webClient = WebClient.builder()
|
||||
.exchangeStrategies { strategies ->
|
||||
strategies.codecs {
|
||||
//...
|
||||
}
|
||||
}
|
||||
.build()
|
||||
|
||||
val client = WebClient.builder()
|
||||
.exchangeStrategies(strategies)
|
||||
.build()
|
||||
----
|
||||
|
||||
Once built, a `WebClient` instance is immutable. However, you can clone it and build a
|
||||
@@ -95,7 +93,44 @@ modified copy without affecting the original instance, as the following example
|
||||
// client2 has filterA, filterB, filterC, filterD
|
||||
----
|
||||
|
||||
[[webflux-client-builder-maxinmemorysize]]
|
||||
=== MaxInMemorySize
|
||||
|
||||
Spring WebFlux configures by default a maximum size for buffering data in-memory when decoding
|
||||
HTTP responses with the `WebClient`. This avoids application memory issues if the received
|
||||
response is much larger than expected.
|
||||
|
||||
The default configured value of 256KB might not be enough for your use case, and your application
|
||||
might hit that limit with the following:
|
||||
|
||||
----
|
||||
org.springframework.core.io.buffer.DataBufferLimitException: Exceeded limit on max bytes to buffer
|
||||
----
|
||||
|
||||
You can configure this limit on all default codecs with the following code sample:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
WebClient webClient = WebClient.builder()
|
||||
.exchangeStrategies(configurer ->
|
||||
configurer.codecs(codecs ->
|
||||
codecs.defaultCodecs().maxInMemorySize(2 * 1024 * 1024)
|
||||
)
|
||||
)
|
||||
.build();
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
val webClient = WebClient.builder()
|
||||
.exchangeStrategies { strategies ->
|
||||
strategies.codecs {
|
||||
it.defaultCodecs().maxInMemorySize(2 * 1024 * 1024)
|
||||
}
|
||||
}
|
||||
.build()
|
||||
----
|
||||
|
||||
[[webflux-client-builder-reactor]]
|
||||
=== Reactor Netty
|
||||
|
||||
Reference in New Issue
Block a user