Add extendMessageConverters to WebMvcConfigurer

Issue: SPR-12450
This commit is contained in:
Rossen Stoyanchev 2014-11-24 15:22:14 -05:00
parent f39c505069
commit 24834f6d2f
7 changed files with 61 additions and 9 deletions

View File

@ -105,6 +105,11 @@ public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
this.configurers.configureMessageConverters(converters);
}
@Override
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
this.configurers.extendMessageConverters(converters);
}
@Override
protected void addFormatters(FormatterRegistry registry) {
this.configurers.addFormatters(registry);

View File

@ -629,6 +629,7 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
if (this.messageConverters.isEmpty()) {
addDefaultHttpMessageConverters(this.messageConverters);
}
extendMessageConverters(this.messageConverters);
}
return this.messageConverters;
}
@ -646,6 +647,9 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
}
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
}
/**
* Adds a set of default HttpMessageConverter instances to the given list.
* Subclasses can call this method from {@link #configureMessageConverters(List)}.

View File

@ -53,14 +53,26 @@ public interface WebMvcConfigurer {
void addFormatters(FormatterRegistry registry);
/**
* Configure the {@link HttpMessageConverter}s to use in argument resolvers
* and return value handlers that support reading and/or writing to the
* body of the request and response. If no message converters are added to
* the list, default converters are added instead.
* Configure the {@link HttpMessageConverter}s to use for reading or writing
* to the body of the request or response. If no converters are added, a
* default list of converters is registered.
* <p><strong>Note</strong> that adding converters to the list, turns off
* default converter registration. To simply add a converter without impacting
* default registration, consider using the method
* {@link #extendMessageConverters(java.util.List)} instead.
* @param converters initially an empty list of converters
*/
void configureMessageConverters(List<HttpMessageConverter<?>> converters);
/**
* A hook for extending or modifying the list of converters after it has been
* configured. This may be useful for example to allow default converters to
* be registered and then insert a custom converter through this method.
* @param converters the list of configured converters to extend.
* @since 4.1.3
*/
void extendMessageConverters(List<HttpMessageConverter<?>> converters);
/**
* Provide a custom {@link Validator} instead of the one created by default.
* The default implementation, assuming JSR-303 is on the classpath, is:

View File

@ -51,6 +51,14 @@ public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
}
/**
* {@inheritDoc}
* <p>This implementation is empty.
*/
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
}
/**
* {@inheritDoc}
* <p>This implementation returns {@code null}

View File

@ -78,6 +78,13 @@ class WebMvcConfigurerComposite implements WebMvcConfigurer {
}
}
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
for (WebMvcConfigurer delegate : this.delegates) {
delegate.extendMessageConverters(converters);
}
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
for (WebMvcConfigurer delegate : this.delegates) {

View File

@ -29,6 +29,7 @@ import org.mockito.MockitoAnnotations;
import org.springframework.core.convert.ConversionService;
import org.springframework.format.support.FormattingConversionService;
import org.springframework.http.HttpMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.util.PathMatcher;
@ -115,18 +116,26 @@ public class DelegatingWebMvcConfigurationTests {
@Test
public void configureMessageConverters() {
final HttpMessageConverter customConverter = mock(HttpMessageConverter.class);
final StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
List<WebMvcConfigurer> configurers = new ArrayList<WebMvcConfigurer>();
configurers.add(new WebMvcConfigurerAdapter() {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new StringHttpMessageConverter());
converters.add(stringConverter);
}
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(0, customConverter);
}
});
delegatingConfig = new DelegatingWebMvcConfiguration();
delegatingConfig.setConfigurers(configurers);
RequestMappingHandlerAdapter adapter = delegatingConfig.requestMappingHandlerAdapter();
assertEquals("Only one custom converter should be registered", 1, adapter.getMessageConverters().size());
assertEquals("Only one custom converter should be registered", 2, adapter.getMessageConverters().size());
assertSame(customConverter, adapter.getMessageConverters().get(0));
assertSame(stringConverter, adapter.getMessageConverters().get(1));
}
@Test

View File

@ -33,6 +33,7 @@ import org.springframework.format.FormatterRegistry;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.mock.web.test.MockHttpServletRequest;
import org.springframework.mock.web.test.MockServletContext;
@ -165,9 +166,10 @@ public class WebMvcConfigurationSupportExtensionTests {
assertEquals("converted", actual);
// Message converters
assertEquals(1, adapter.getMessageConverters().size());
assertEquals(MappingJackson2HttpMessageConverter.class, adapter.getMessageConverters().get(0).getClass());
ObjectMapper objectMapper = ((MappingJackson2HttpMessageConverter)adapter.getMessageConverters().get(0)).getObjectMapper();
assertEquals(2, adapter.getMessageConverters().size());
assertEquals(StringHttpMessageConverter.class, adapter.getMessageConverters().get(0).getClass());
assertEquals(MappingJackson2HttpMessageConverter.class, adapter.getMessageConverters().get(1).getClass());
ObjectMapper objectMapper = ((MappingJackson2HttpMessageConverter)adapter.getMessageConverters().get(1)).getObjectMapper();
assertFalse(objectMapper.getDeserializationConfig().isEnabled(MapperFeature.DEFAULT_VIEW_INCLUSION));
assertFalse(objectMapper.getSerializationConfig().isEnabled(MapperFeature.DEFAULT_VIEW_INCLUSION));
assertFalse(objectMapper.getDeserializationConfig().isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES));
@ -301,6 +303,11 @@ public class WebMvcConfigurationSupportExtensionTests {
converters.add(new MappingJackson2HttpMessageConverter());
}
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(0, new StringHttpMessageConverter());
}
@Override
public Validator getValidator() {
return new Validator() {