Support better HttpMessageConverters manipulation

Add additional constructor and a protected postProcessConverters method
to make it easier to manipulate the final converter list that will
be used.

Fixes gh-1482
pull/1487/merge
Phillip Webb 10 years ago
parent 0c0a0a7738
commit 34cbcf5e50

@ -69,26 +69,54 @@ public class HttpMessageConverters implements Iterable<HttpMessageConverter<?>>
* 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<HttpMessageConverter<?>> additionalConverters) {
List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
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<HttpMessageConverter<?>> converters) {
List<HttpMessageConverter<?>> combined = new ArrayList<HttpMessageConverter<?>>();
List<HttpMessageConverter<?>> processing = new ArrayList<HttpMessageConverter<?>>(
additionalConverters);
for (HttpMessageConverter<?> defaultConverter : getDefaultConverters()) {
Iterator<HttpMessageConverter<?>> 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<HttpMessageConverter<?>> 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<HttpMessageConverter<?>> postProcessConverters(
List<HttpMessageConverter<?>> converters) {
return converters;
}
private List<HttpMessageConverter<?>> getDefaultConverters() {
@ -127,8 +155,8 @@ public class HttpMessageConverters implements Iterable<HttpMessageConverter<?>>
}
/**
* 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<HttpMessageConverter<?>> getConverters() {

@ -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<HttpMessageConverter<?>> postProcessConverters(
List<HttpMessageConverter<?>> converters) {
for (Iterator<HttpMessageConverter<?>> iterator = converters.iterator(); iterator
.hasNext();) {
if (iterator.next() instanceof Jaxb2RootElementHttpMessageConverter) {
iterator.remove();
}
}
return converters;
};
};
List<Class<?>> converterClasses = new ArrayList<Class<?>>();
for (HttpMessageConverter<?> converter : converters) {
converterClasses.add(converter.getClass());
}
assertThat(converterClasses, equalTo(Arrays.<Class<?>> asList(
ByteArrayHttpMessageConverter.class, StringHttpMessageConverter.class,
ResourceHttpMessageConverter.class, SourceHttpMessageConverter.class,
AllEncompassingFormHttpMessageConverter.class,
MappingJackson2HttpMessageConverter.class)));
}
}

Loading…
Cancel
Save