diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/HttpMessageConverters.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/HttpMessageConverters.java index bb2eb8633f5..4b0290e1b1d 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/HttpMessageConverters.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/HttpMessageConverters.java @@ -69,26 +69,54 @@ public class HttpMessageConverters implements Iterable> * converters. * @param additionalConverters additional converters to be added. Items are added just * before any default converter of the same type (or at the front of the list if no - * default converter is found) The {@link #getConverters()} methods can be used for - * further converter manipulation. + * default converter is found) The {@link #postProcessConverters(List)} method can be + * used for further converter manipulation. */ public HttpMessageConverters(Collection> additionalConverters) { - List> converters = new ArrayList>(); + this(true, additionalConverters); + } + + /** + * Create a new {@link HttpMessageConverters} instance with the specified converters. + * @param addDefaultConverters if default converters should be added + * @param converters converters to be added. Items are added just before any default + * converter of the same type (or at the front of the list if no default converter is + * found) The {@link #postProcessConverters(List)} method can be used for further + * converter manipulation. + */ + public HttpMessageConverters(boolean addDefaultConverters, + Collection> converters) { + List> combined = new ArrayList>(); List> processing = new ArrayList>( - additionalConverters); - for (HttpMessageConverter defaultConverter : getDefaultConverters()) { - Iterator> iterator = processing.iterator(); - while (iterator.hasNext()) { - HttpMessageConverter candidate = iterator.next(); - if (ClassUtils.isAssignableValue(defaultConverter.getClass(), candidate)) { - converters.add(candidate); - iterator.remove(); + converters); + if (addDefaultConverters) { + for (HttpMessageConverter defaultConverter : getDefaultConverters()) { + Iterator> iterator = processing.iterator(); + while (iterator.hasNext()) { + HttpMessageConverter candidate = iterator.next(); + if (ClassUtils.isAssignableValue(defaultConverter.getClass(), + candidate)) { + combined.add(candidate); + iterator.remove(); + } } + combined.add(defaultConverter); } - converters.add(defaultConverter); } - converters.addAll(0, processing); - this.converters = Collections.unmodifiableList(converters); + combined.addAll(0, processing); + combined = postProcessConverters(combined); + this.converters = Collections.unmodifiableList(combined); + } + + /** + * Method that can be used to post-process the {@link HttpMessageConverter} list + * before it is used. + * @param converters a mutable list of the converters that will be used. + * @return the final converts list to use + */ + protected List> postProcessConverters( + List> converters) { + return converters; } private List> getDefaultConverters() { @@ -127,8 +155,8 @@ public class HttpMessageConverters implements Iterable> } /** - * Return a mutable list of the converters in the order that they will be registered. - * Values in the list cannot be modified once the bean has been initialized. + * Return an immutable list of the converters in the order that they will be + * registered. * @return the converters */ public List> getConverters() { diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/HttpMessageConvertersTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/HttpMessageConvertersTests.java index 91ae26af35e..6363679f1be 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/HttpMessageConvertersTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/HttpMessageConvertersTests.java @@ -18,6 +18,7 @@ package org.springframework.boot.autoconfigure.web; import java.util.ArrayList; import java.util.Arrays; +import java.util.Iterator; import java.util.List; import org.junit.Rule; @@ -97,4 +98,30 @@ public class HttpMessageConvertersTests { assertEquals(converter2, converters.getConverters().get(1)); } + @Test + public void postProcessConverters() throws Exception { + HttpMessageConverters converters = new HttpMessageConverters() { + @Override + protected List> postProcessConverters( + List> converters) { + for (Iterator> iterator = converters.iterator(); iterator + .hasNext();) { + if (iterator.next() instanceof Jaxb2RootElementHttpMessageConverter) { + iterator.remove(); + } + } + return converters; + }; + }; + List> converterClasses = new ArrayList>(); + for (HttpMessageConverter converter : converters) { + converterClasses.add(converter.getClass()); + } + assertThat(converterClasses, equalTo(Arrays.> asList( + ByteArrayHttpMessageConverter.class, StringHttpMessageConverter.class, + ResourceHttpMessageConverter.class, SourceHttpMessageConverter.class, + AllEncompassingFormHttpMessageConverter.class, + MappingJackson2HttpMessageConverter.class))); + } + }