Configure HttpMessageConverters as a list

This commit adds a new `configureMessageConvertersList` method on the
builder to add/remove/move converters in the resulting list before they
are individually post-processed.

This allows to re-introduce a behavior that was missing with the new
contract: the ability to append a converter at the end of the list.

See gh-36083

Signed-off-by: hayden.rear <hayden.rear@gmail.com>
This commit is contained in:
hayden.rear
2026-01-07 14:29:05 +01:00
committed by Brian Clozel
parent e94aaab288
commit c7413cbdfc
3 changed files with 77 additions and 0 deletions
@@ -122,6 +122,8 @@ class DefaultHttpMessageConverters implements HttpMessageConverters {
@Nullable Consumer<HttpMessageConverter<?>> configurer;
@Nullable Consumer<List<HttpMessageConverter<?>>> convertersListConfigurer;
@Nullable HttpMessageConverter<?> kotlinJsonConverter;
@Nullable HttpMessageConverter<?> jsonConverter;
@@ -226,6 +228,10 @@ class DefaultHttpMessageConverters implements HttpMessageConverters {
this.configurer = (this.configurer != null) ? configurer.andThen(this.configurer) : configurer;
}
void addMessageConvertersListConfigurer(Consumer<List<HttpMessageConverter<?>>> configurer) {
this.convertersListConfigurer = (this.convertersListConfigurer != null) ? this.convertersListConfigurer.andThen(this.convertersListConfigurer) : configurer;
}
List<HttpMessageConverter<?>> getBaseConverters() {
List<HttpMessageConverter<?>> converters = new ArrayList<>();
if (this.byteArrayConverter != null) {
@@ -442,6 +448,12 @@ class DefaultHttpMessageConverters implements HttpMessageConverters {
return this;
}
@Override
public ClientBuilder configureMessageConvertersList(Consumer<List<HttpMessageConverter<?>>> configurer) {
addMessageConvertersListConfigurer(configurer);
return this;
}
@Override
public HttpMessageConverters build() {
if (this.registerDefaults) {
@@ -466,6 +478,10 @@ class DefaultHttpMessageConverters implements HttpMessageConverters {
if (this.configurer != null) {
allConverters.forEach(this.configurer);
}
if (this.convertersListConfigurer != null) {
this.convertersListConfigurer.accept(allConverters);
}
return new DefaultHttpMessageConverters(allConverters);
}
}
@@ -539,6 +555,12 @@ class DefaultHttpMessageConverters implements HttpMessageConverters {
return this;
}
@Override
public ServerBuilder configureMessageConvertersList(Consumer<List<HttpMessageConverter<?>>> configurer) {
addMessageConvertersListConfigurer(configurer);
return this;
}
@Override
public HttpMessageConverters build() {
if (this.registerDefaults) {
@@ -567,6 +589,10 @@ class DefaultHttpMessageConverters implements HttpMessageConverters {
if (this.configurer != null) {
allConverters.forEach(this.configurer);
}
if (this.convertersListConfigurer != null) {
this.convertersListConfigurer.accept(allConverters);
}
return new DefaultHttpMessageConverters(allConverters);
}
}
@@ -16,6 +16,7 @@
package org.springframework.http.converter;
import java.util.List;
import java.util.function.Consumer;
/**
@@ -172,6 +173,12 @@ public interface HttpMessageConverters extends Iterable<HttpMessageConverter<?>>
*/
T configureMessageConverters(Consumer<HttpMessageConverter<?>> configurer);
/**
* Add a consumer for configuring the message converters list just before it's returned.
* @param configurer the configurer to use
*/
T configureMessageConvertersList(Consumer<List<HttpMessageConverter<?>>> configurer);
/**
* Build and return the {@link HttpMessageConverters} instance configured by this builder.
*/