diff --git a/spring-messaging/src/main/java/org/springframework/messaging/converter/AbstractMessageConverter.java b/spring-messaging/src/main/java/org/springframework/messaging/converter/AbstractMessageConverter.java index bf48901f92..3cef560277 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/converter/AbstractMessageConverter.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/converter/AbstractMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,10 +32,10 @@ import org.springframework.util.Assert; import org.springframework.util.MimeType; /** - * Abstract base class for {@link MessageConverter} implementations including support for - * common properties and a partial implementation of the conversion methods mainly to - * check if the converter supports the conversion based on the payload class and MIME - * type. + * Abstract base class for {@link MessageConverter} implementations including support + * for common properties and a partial implementation of the conversion methods, + * mainly to check if the converter supports the conversion based on the payload class + * and MIME type. * * @author Rossen Stoyanchev * @since 4.0 @@ -68,7 +68,7 @@ public abstract class AbstractMessageConverter implements MessageConverter { * @param supportedMimeTypes the supported MIME types */ protected AbstractMessageConverter(Collection supportedMimeTypes) { - Assert.notNull(supportedMimeTypes, "SupportedMimeTypes must not be null"); + Assert.notNull(supportedMimeTypes, "supportedMimeTypes must not be null"); this.supportedMimeTypes = new ArrayList(supportedMimeTypes); } @@ -83,13 +83,11 @@ public abstract class AbstractMessageConverter implements MessageConverter { /** * Configure the {@link ContentTypeResolver} to use to resolve the content * type of an input message. - *

- * Note that if no resolver is configured, then + *

Note that if no resolver is configured, then * {@link #setStrictContentTypeMatch(boolean) strictContentTypeMatch} should * be left as {@code false} (the default) or otherwise this converter will * ignore all messages. - *

- * By default, a {@code DefaultContentTypeResolver} instance is used. + *

By default, a {@code DefaultContentTypeResolver} instance is used. */ public void setContentTypeResolver(ContentTypeResolver resolver) { this.contentTypeResolver = resolver; @@ -106,20 +104,17 @@ public abstract class AbstractMessageConverter implements MessageConverter { * Whether this converter should convert messages for which no content type * could be resolved through the configured * {@link org.springframework.messaging.converter.ContentTypeResolver}. - * A converter can configured to be strict only when a - * {@link #setContentTypeResolver(ContentTypeResolver) contentTypeResolver} - * is configured and the list of {@link #getSupportedMimeTypes() supportedMimeTypes} - * is not be empty. - * - * then requires the content type of a message to be resolved - * - * When set to true, #supportsMimeType(MessageHeaders) will return false if the - * contentTypeResolver is not defined or if no content-type header is present. + *

A converter can configured to be strict only when a + * {@link #setContentTypeResolver contentTypeResolver} is configured and the + * list of {@link #getSupportedMimeTypes() supportedMimeTypes} is not be empty. + *

When this flag is set to {@code true}, {@link #supportsMimeType(MessageHeaders)} + * will return {@code false} if the {@link #setContentTypeResolver contentTypeResolver} + * is not defined or if no content-type header is present. */ public void setStrictContentTypeMatch(boolean strictContentTypeMatch) { if (strictContentTypeMatch) { - Assert.notEmpty(getSupportedMimeTypes(), "Strict match requires non-empty list of supported mime types."); - Assert.notNull(getContentTypeResolver(), "Strict match requires ContentTypeResolver."); + Assert.notEmpty(getSupportedMimeTypes(), "Strict match requires non-empty list of supported mime types"); + Assert.notNull(getContentTypeResolver(), "Strict match requires ContentTypeResolver"); } this.strictContentTypeMatch = strictContentTypeMatch; } @@ -166,14 +161,6 @@ public abstract class AbstractMessageConverter implements MessageConverter { return (!mimeTypes.isEmpty() ? mimeTypes.get(0) : null); } - /** - * Whether the given class is supported by this converter. - * @param clazz the class to test for support - * @return {@code true} if supported; {@code false} otherwise - */ - protected abstract boolean supports(Class clazz); - - @Override public final Object fromMessage(Message message, Class targetClass) { if (!canConvertFrom(message, targetClass)) { @@ -186,14 +173,8 @@ public abstract class AbstractMessageConverter implements MessageConverter { return (supports(targetClass) && supportsMimeType(message.getHeaders())); } - /** - * Convert the message payload from serialized form to an Object. - */ - public abstract Object convertFromInternal(Message message, Class targetClass); - @Override public final Message toMessage(Object payload, MessageHeaders headers) { - if (!canConvertTo(payload, headers)) { return null; } @@ -218,15 +199,10 @@ public abstract class AbstractMessageConverter implements MessageConverter { } protected boolean canConvertTo(Object payload, MessageHeaders headers) { - Class clazz = (payload != null) ? payload.getClass() : null; + Class clazz = (payload != null ? payload.getClass() : null); return (supports(clazz) && supportsMimeType(headers)); } - /** - * Convert the payload object to serialized form. - */ - public abstract Object convertToInternal(Object payload, MessageHeaders headers); - protected boolean supportsMimeType(MessageHeaders headers) { if (getSupportedMimeTypes().isEmpty()) { return true; @@ -249,7 +225,26 @@ public abstract class AbstractMessageConverter implements MessageConverter { } protected MimeType getMimeType(MessageHeaders headers) { - return (this.contentTypeResolver != null) ? this.contentTypeResolver.resolve(headers) : null; + return (this.contentTypeResolver != null ? this.contentTypeResolver.resolve(headers) : null); } + + /** + * Whether the given class is supported by this converter. + * @param clazz the class to test for support + * @return {@code true} if supported; {@code false} otherwise + */ + protected abstract boolean supports(Class clazz); + + /** + * Convert the message payload from serialized form to an Object. + */ + public abstract Object convertFromInternal(Message message, Class targetClass); + + + /** + * Convert the payload object to serialized form. + */ + public abstract Object convertToInternal(Object payload, MessageHeaders headers); + } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/converter/MappingJackson2MessageConverter.java b/spring-messaging/src/main/java/org/springframework/messaging/converter/MappingJackson2MessageConverter.java index 1578f9dea3..2ee1789484 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/converter/MappingJackson2MessageConverter.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/converter/MappingJackson2MessageConverter.java @@ -21,7 +21,7 @@ import java.io.IOException; import java.io.StringWriter; import java.io.Writer; import java.nio.charset.Charset; -import java.util.Collection; +import java.util.Arrays; import java.util.concurrent.atomic.AtomicReference; import com.fasterxml.jackson.core.JsonEncoding; @@ -68,33 +68,27 @@ public class MappingJackson2MessageConverter extends AbstractMessageConverter { /** - * Construct a {@code MappingJackson2MessageConverter} supporting {@code application/json} MIME type. + * Construct a {@code MappingJackson2MessageConverter} supporting + * the {@code application/json} MIME type. */ public MappingJackson2MessageConverter() { - this(new MimeType("application", "json", Charset.forName("UTF-8"))); + super(new MimeType("application", "json", Charset.forName("UTF-8"))); + initObjectMapper(); } /** - * Construct a {@code MappingJackson2MessageConverter} supporting a single MIME type. - * @param supportedMimeType the supported MIME type - * @since 4.1.5 - */ - public MappingJackson2MessageConverter(MimeType supportedMimeType) { - super(supportedMimeType); - init(); - } - - /** - * Construct a {@code MappingJackson2MessageConverter} supporting multiple MIME types. + * Construct a {@code MappingJackson2MessageConverter} supporting + * one or more custom MIME types. * @param supportedMimeTypes the supported MIME types * @since 4.1.5 */ - public MappingJackson2MessageConverter(Collection supportedMimeTypes) { - super(supportedMimeTypes); - init(); + public MappingJackson2MessageConverter(MimeType... supportedMimeTypes) { + super(Arrays.asList(supportedMimeTypes)); + initObjectMapper(); } - private void init() { + + private void initObjectMapper() { this.objectMapper = new ObjectMapper(); this.objectMapper.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, false); this.objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); diff --git a/spring-messaging/src/test/java/org/springframework/messaging/converter/MappingJackson2MessageConverterTests.java b/spring-messaging/src/test/java/org/springframework/messaging/converter/MappingJackson2MessageConverterTests.java index e3da343dae..0faeca6066 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/converter/MappingJackson2MessageConverterTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/converter/MappingJackson2MessageConverterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +23,6 @@ import java.util.HashMap; import java.util.Map; import com.fasterxml.jackson.databind.DeserializationFeature; -import static org.hamcrest.Matchers.contains; import org.junit.Test; import org.springframework.messaging.Message; @@ -31,17 +30,20 @@ import org.springframework.messaging.MessageHeaders; import org.springframework.messaging.support.MessageBuilder; import org.springframework.util.MimeType; +import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; /** * Test fixture for {@link org.springframework.messaging.converter.MappingJackson2MessageConverter}. * * @author Rossen Stoyanchev + * @author Sebastien Deleuze */ public class MappingJackson2MessageConverterTests { private static Charset UTF_8 = Charset.forName("UTF-8"); + @Test public void defaultConstructor() { MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter(); @@ -49,7 +51,7 @@ public class MappingJackson2MessageConverterTests { assertFalse(converter.getObjectMapper().getDeserializationConfig().isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)); } - @Test // SPR-12724 + @Test // SPR-12724 public void mimetypeParametrizedConstructor() { MimeType mimetype = new MimeType("application", "xml", UTF_8); MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter(mimetype); @@ -57,11 +59,11 @@ public class MappingJackson2MessageConverterTests { assertFalse(converter.getObjectMapper().getDeserializationConfig().isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)); } - @Test // SPR-12724 + @Test // SPR-12724 public void mimetypesParametrizedConstructor() { MimeType jsonMimetype = new MimeType("application", "json", UTF_8); MimeType xmlMimetype = new MimeType("application", "xml", UTF_8); - MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter(Arrays.asList(jsonMimetype, xmlMimetype)); + MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter(jsonMimetype, xmlMimetype); assertThat(converter.getSupportedMimeTypes(), contains(jsonMimetype, xmlMimetype)); assertFalse(converter.getObjectMapper().getDeserializationConfig().isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)); }