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
@@ -17,9 +17,11 @@
package org.springframework.http.converter;
import java.io.IOException;
import java.util.Comparator;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import org.assertj.core.util.Lists;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
@@ -211,6 +213,27 @@ class DefaultHttpMessageConvertersTests {
assertThat(customConverter.processed).isTrue();
}
@Test
void shouldConfigureConverterOrder() {
var customConverter = new CustomHttpMessageConverter();
var converted = HttpMessageConverters.forClient()
.addCustomConverter(customConverter)
.configureMessageConvertersList(converter -> converter.sort(Comparator.comparing(s -> s.getClass().equals(CustomHttpMessageConverter.class) ? 1 : -1))).build();
var messageConvertersBack = Lists.newArrayList(converted);
assertThat(messageConvertersBack.size()).isGreaterThan(1);
assertThat(messageConvertersBack.get(messageConvertersBack.size() - 1).getClass()).isEqualTo(CustomHttpMessageConverter.class);
var convertedFront = HttpMessageConverters.forClient()
.addCustomConverter(customConverter)
.configureMessageConvertersList(converter -> converter.sort(Comparator.comparing(s -> s.getClass().equals(CustomHttpMessageConverter.class) ? -1 : 1))).build();
var messageConvertersFront = Lists.newArrayList(convertedFront);
assertThat(messageConvertersFront.get(0).getClass()).isEqualTo(CustomHttpMessageConverter.class);
assertThat(messageConvertersFront.size()).isGreaterThan(1);
}
}
@@ -319,6 +342,27 @@ class DefaultHttpMessageConvertersTests {
assertThat(customConverter.processed).isTrue();
}
@Test
void shouldConfigureConverterOrder() {
var customConverter = new CustomHttpMessageConverter();
var converted = HttpMessageConverters.forServer()
.addCustomConverter(customConverter)
.configureMessageConvertersList(converter -> converter.sort(Comparator.comparing(s -> s.getClass().equals(CustomHttpMessageConverter.class) ? 1 : -1))).build();
var messageConvertersBack = Lists.newArrayList(converted);
assertThat(messageConvertersBack.size()).isGreaterThan(1);
assertThat(messageConvertersBack.get(messageConvertersBack.size() - 1).getClass()).isEqualTo(CustomHttpMessageConverter.class);
var convertedFront = HttpMessageConverters.forServer()
.addCustomConverter(customConverter)
.configureMessageConvertersList(converter -> converter.sort(Comparator.comparing(s -> s.getClass().equals(CustomHttpMessageConverter.class) ? -1 : 1))).build();
var messageConvertersFront = Lists.newArrayList(convertedFront);
assertThat(messageConvertersFront.size()).isGreaterThan(1);
assertThat(messageConvertersFront.get(0).getClass()).isEqualTo(CustomHttpMessageConverter.class);
}
}
@SuppressWarnings("unchecked")