Remove ContentTypeResolver from composite converter

Before this change CompositeMessageConverter had a ContentTypeResolver
field that was in turn set on all contained converters.

After this change that field is removed and effectively
CompositeMessageConverter is a simple container of other converters.
Each converter in turn must have been configured with a
ContentTypeResolver.

Doing so means it is less likely to have unexpected consequences when
configuring converters, the ContentTypeResolver set in the composite
converter overriding the one configured in a contained converter.

Also commit 676ce6 added default ContentTypeResolver initialization
to AbstractMessageConverter, which ensures that converters are still
straight forward to configure.

Issue: SPR-11462
This commit is contained in:
Rossen Stoyanchev
2014-02-27 21:25:10 -05:00
parent 0da1eefd74
commit 6016536055
6 changed files with 40 additions and 85 deletions

View File

@@ -25,8 +25,8 @@ import org.springframework.messaging.MessageHeaders;
import org.springframework.util.Assert;
/**
* A {@link MessageConverter} that delegates to a list of other converters to invoke until
* one of them returns a non-null value.
* A {@link MessageConverter} that delegates to a list of other converters
* to be invoked until one of them returns a non-null result.
*
* @author Rossen Stoyanchev
* @since 4.0
@@ -35,51 +35,16 @@ public class CompositeMessageConverter implements MessageConverter {
private final List<MessageConverter> converters;
private ContentTypeResolver contentTypeResolver;
/**
* Create a new instance with the given {@link MessageConverter}s in turn configuring
* each with a {@link DefaultContentTypeResolver}.
* Create an instance with the given converters.
*/
public CompositeMessageConverter(Collection<MessageConverter> converters) {
this(new ArrayList<MessageConverter>(converters), new DefaultContentTypeResolver());
}
/**
* Create an instance with the given {@link MessageConverter}s and configure all with
* the given {@link ContentTypeResolver}.
*/
public CompositeMessageConverter(Collection<MessageConverter> converters, ContentTypeResolver resolver) {
Assert.notEmpty(converters, "Converters must not be null");
Assert.notNull(resolver, "ContentTypeResolver must not be null");
Assert.notEmpty(converters, "Converters must not be empty");
this.converters = new ArrayList<MessageConverter>(converters);
this.contentTypeResolver = resolver;
applyContentTypeResolver(converters, resolver);
}
private static void applyContentTypeResolver(Collection<MessageConverter> converters,
ContentTypeResolver resolver) {
for (MessageConverter converter : converters) {
if (converter instanceof AbstractMessageConverter) {
((AbstractMessageConverter) converter).setContentTypeResolver(resolver);
}
}
}
public void setContentTypeResolver(ContentTypeResolver resolver) {
this.contentTypeResolver = resolver;
applyContentTypeResolver(getConverters(), resolver);
}
public ContentTypeResolver getContentTypeResolver() {
return this.contentTypeResolver;
}
public Collection<MessageConverter> getConverters() {
public List<MessageConverter> getConverters() {
return this.converters;
}
@@ -108,7 +73,7 @@ public class CompositeMessageConverter implements MessageConverter {
@Override
public String toString() {
return "CompositeMessageConverter[contentTypeResolver=" + this.contentTypeResolver +
", converters=" + this.converters + "]";
return "CompositeMessageConverter[converters=" + this.converters + "]";
}
}

View File

@@ -248,26 +248,20 @@ public abstract class AbstractMessageBrokerConfiguration implements ApplicationC
@Bean
public CompositeMessageConverter brokerMessageConverter() {
List<MessageConverter> converters = new ArrayList<MessageConverter>();
boolean registerDefaults = configureMessageConverters(converters);
if (registerDefaults) {
if (jackson2Present) {
converters.add(new MappingJackson2MessageConverter());
DefaultContentTypeResolver resolver = new DefaultContentTypeResolver();
resolver.setDefaultMimeType(MimeTypeUtils.APPLICATION_JSON);
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setContentTypeResolver(resolver);
converters.add(converter);
}
converters.add(new StringMessageConverter());
converters.add(new ByteArrayMessageConverter());
}
ContentTypeResolver contentTypeResolver = getContentTypeResolver();
if (contentTypeResolver == null) {
contentTypeResolver = new DefaultContentTypeResolver();
if (jackson2Present && registerDefaults) {
((DefaultContentTypeResolver) contentTypeResolver).setDefaultMimeType(MimeTypeUtils.APPLICATION_JSON);
}
}
return new CompositeMessageConverter(converters, contentTypeResolver);
return new CompositeMessageConverter(converters);
}
/**
@@ -281,13 +275,6 @@ public abstract class AbstractMessageBrokerConfiguration implements ApplicationC
return true;
}
/**
* Override this method to provide a custom {@link ContentTypeResolver}.
*/
protected ContentTypeResolver getContentTypeResolver() {
return null;
}
@Bean
public UserDestinationResolver userDestinationResolver() {
DefaultUserDestinationResolver resolver = new DefaultUserDestinationResolver(userSessionRegistry());