From 7021d2195d8431d3f89318aac8065cd4e934d02b Mon Sep 17 00:00:00 2001 From: Ilayaperumal Gopinathan Date: Thu, 3 Mar 2016 21:27:09 +0530 Subject: [PATCH] Set string value for originalContentType in message header - Since the `originalContentType` header is preserved across the wire while the serialization/de-serialization processes take place using the deduced `contentType`, it is convenient to set the `String` value of the `originalContentType` instead of setting the actual `MimeType` object in the header. - Once the `de-serialization` has taken place, the deduced `contentType` is always replaced with the `originalContentType` as the `contentType` in the message header and this preserved contentType can be resolved to its corresponding MimeType using `ContentTypeResolver` anytime. Hence, using the `String` object for `originalContentType` doesn't do any harm. - Fix the issue while setting the deduced contentType based on the `payload` when the `originalContentType` is `application/json` - Currently, the contentType is set to `text/plain` which seems incorrect - Also, add the `application/json` contentType to return `String` object during de-serialization process. This resolves #383 Use `text/plain` contentType when the payload is of type `String` - This is for the intermediate contentType that is used for serialization/de-serialization --- .../MessageChannelBinderSupportTests.java | 5 ++- .../cloud/stream/binder/AbstractBinder.java | 45 +++++++++---------- 2 files changed, 23 insertions(+), 27 deletions(-) diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-test/src/test/java/org/springframework/cloud/stream/binder/MessageChannelBinderSupportTests.java b/spring-cloud-stream-binders/spring-cloud-stream-binder-test/src/test/java/org/springframework/cloud/stream/binder/MessageChannelBinderSupportTests.java index 4cc2287a8..c8389214e 100644 --- a/spring-cloud-stream-binders/spring-cloud-stream-binder-test/src/test/java/org/springframework/cloud/stream/binder/MessageChannelBinderSupportTests.java +++ b/spring-cloud-stream-binders/spring-cloud-stream-binder-test/src/test/java/org/springframework/cloud/stream/binder/MessageChannelBinderSupportTests.java @@ -50,6 +50,7 @@ import com.esotericsoftware.kryo.Registration; /** * @author Gary Russell * @author David Turanski + * @author Ilayaperumal Gopinathan */ public class MessageChannelBinderSupportTests { @@ -122,11 +123,11 @@ public class MessageChannelBinderSupportTests { assertEquals(MimeTypeUtils.TEXT_PLAIN, contentTypeResolver.resolve(converted.getHeaders())); - assertEquals(MimeTypeUtils.APPLICATION_JSON, + assertEquals(MimeTypeUtils.APPLICATION_JSON.toString(), converted.getHeaders().get(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE)); MessageValues reconstructed = binder.deserializePayloadIfNecessary(converted); assertEquals("{\"foo\":\"foo\"}", reconstructed.getPayload()); - assertEquals(MimeTypeUtils.APPLICATION_JSON, reconstructed.get(MessageHeaders.CONTENT_TYPE)); + assertEquals(MimeTypeUtils.APPLICATION_JSON.toString(), reconstructed.get(MessageHeaders.CONTENT_TYPE)); } @Test diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/AbstractBinder.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/AbstractBinder.java index 567a9c725..9bc1d2d4f 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/AbstractBinder.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/AbstractBinder.java @@ -17,9 +17,7 @@ package org.springframework.cloud.stream.binder; import static org.springframework.util.MimeTypeUtils.APPLICATION_OCTET_STREAM; -import static org.springframework.util.MimeTypeUtils.APPLICATION_OCTET_STREAM_VALUE; import static org.springframework.util.MimeTypeUtils.TEXT_PLAIN; -import static org.springframework.util.MimeTypeUtils.TEXT_PLAIN_VALUE; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -57,6 +55,7 @@ import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.IdGenerator; import org.springframework.util.MimeType; +import org.springframework.util.MimeTypeUtils; import org.springframework.util.StringUtils; /** @@ -370,7 +369,7 @@ public abstract class AbstractBinder implements ApplicationContextAware, Init messageValues.setPayload(payload); messageValues.put(MessageHeaders.CONTENT_TYPE, contentType); if (originalContentType != null) { - messageValues.put(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE, originalContentType); + messageValues.put(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE, originalContentType.toString()); } return messageValues; } @@ -399,18 +398,18 @@ public abstract class AbstractBinder implements ApplicationContextAware, Init return deserializePayloadIfNecessary(new MessageValues(message)); } - protected final MessageValues deserializePayloadIfNecessary(MessageValues message) { - Object originalPayload = message.getPayload(); - MimeType contentType = this.contentTypeResolver.resolve(message); + protected final MessageValues deserializePayloadIfNecessary(MessageValues messageValues) { + Object originalPayload = messageValues.getPayload(); + MimeType contentType = this.contentTypeResolver.resolve(messageValues); Object payload = deserializePayload(originalPayload, contentType); if (payload != null) { - message.setPayload(payload); + messageValues.setPayload(payload); - Object originalContentType = message.get(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE); - message.put(MessageHeaders.CONTENT_TYPE, originalContentType); - message.put(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE, null); + Object originalContentType = messageValues.get(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE); + messageValues.put(MessageHeaders.CONTENT_TYPE, originalContentType); + messageValues.remove(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE); } - return message; + return messageValues; } private Object deserializePayload(Object payload, MimeType contentType) { @@ -538,31 +537,27 @@ public abstract class AbstractBinder implements ApplicationContextAware, Init /** * Handles representing any java class as a {@link MimeType}. + * * @author David Turanski - * @see + * @author Ilayaperumal Gopinathan */ abstract static class JavaClassMimeTypeConversion { - public static final MimeType APPLICATION_OCTET_STREAM_MIME_TYPE = MimeType.valueOf - (APPLICATION_OCTET_STREAM_VALUE); - - public static final MimeType TEXT_PLAIN_MIME_TYPE = MimeType.valueOf(TEXT_PLAIN_VALUE); - private static ConcurrentMap mimeTypesCache = new ConcurrentHashMap<>(); - static MimeType mimeTypeFromObject(Object obj) { - Assert.notNull(obj, "object cannot be null."); - if (obj instanceof byte[]) { - return APPLICATION_OCTET_STREAM_MIME_TYPE; + static MimeType mimeTypeFromObject(Object payload) { + Assert.notNull(payload, "payload object cannot be null."); + if (payload instanceof byte[]) { + return MimeTypeUtils.APPLICATION_OCTET_STREAM; } - if (obj instanceof String) { - return TEXT_PLAIN_MIME_TYPE; + if (payload instanceof String) { + return MimeTypeUtils.TEXT_PLAIN; } - String className = obj.getClass().getName(); + String className = payload.getClass().getName(); MimeType mimeType = mimeTypesCache.get(className); if (mimeType == null) { String modifiedClassName = className; - if (obj.getClass().isArray()) { + if (payload.getClass().isArray()) { // Need to remove trailing ';' for an object array, e.g. "[Ljava.lang.String;" or multi-dimensional // "[[[Ljava.lang.String;" if (modifiedClassName.endsWith(";")) {