diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/ObjectToStringTransformerParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/ObjectToStringTransformerParser.java index 74c7ab5f01..2ba8796ec4 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/ObjectToStringTransformerParser.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/ObjectToStringTransformerParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2013 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. @@ -16,25 +16,31 @@ package org.springframework.integration.config.xml; -import org.w3c.dom.Element; - import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.integration.transformer.ObjectToStringTransformer; +import org.springframework.util.StringUtils; +import org.w3c.dom.Element; /** * Parser for the 'object-to-string-transformer' element. - * + * * @author Mark Fisher + * @author Gary Russell */ public class ObjectToStringTransformerParser extends AbstractTransformerParser { @Override protected String getTransformerClassName() { - return IntegrationNamespaceUtils.BASE_PACKAGE + ".transformer.ObjectToStringTransformer"; + return ObjectToStringTransformer.class.getName(); } @Override protected void parseTransformer(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { + String charset = element.getAttribute("charset"); + if (StringUtils.hasText(charset)) { + builder.addConstructorArgValue(charset); + } } } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/transformer/ObjectToStringTransformer.java b/spring-integration-core/src/main/java/org/springframework/integration/transformer/ObjectToStringTransformer.java index df3af1de3a..3650b8e8e8 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/transformer/ObjectToStringTransformer.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/transformer/ObjectToStringTransformer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2013 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. @@ -16,18 +16,47 @@ package org.springframework.integration.transformer; +import org.springframework.util.Assert; + + /** * A simple transformer that creates an outbound payload by invoking the - * inbound payload Object's toString() method. - * + * inbound payload Object's toString() method. Unless the + * payload is a byte[] or char[]. If the payload + * is a byte[], it will be transformed to a String containing the + * array's contents, using the {@link #charset} + * which, by default, is "UTF-8". If the payload is a char[], it will be + * transformed to a String object with the array's contents. + * * @author Mark Fisher + * @author Andrew Cowlin + * @author Gary Russell * @since 1.0.1 */ public class ObjectToStringTransformer extends AbstractPayloadTransformer { + private final String charset; + + public ObjectToStringTransformer() { + this.charset = "UTF-8"; + } + + public ObjectToStringTransformer(String charset) { + Assert.notNull(charset, "'charset' cannot be null"); + this.charset = charset; + } + @Override protected String transformPayload(Object payload) throws Exception { - return payload.toString(); + if (payload instanceof byte[]) { + return new String((byte[]) payload, this.charset); + } + else if (payload instanceof char[]) { + return new String((char[]) payload); + } + else { + return payload.toString(); + } } } diff --git a/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-3.0.xsd b/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-3.0.xsd index 66842061a0..b11657c35b 100644 --- a/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-3.0.xsd +++ b/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-3.0.xsd @@ -3837,6 +3837,15 @@ endpoint itself is a Polling Consumer for a channel with a queue. + + + + Allows you to specify the Charset (e.g., US-ASCII, + ISO-8859-1, UTF-8) to be used when transforming byte[]. [UTF-8] is the default + + + diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/ObjectToStringTransformerParserTests-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/ObjectToStringTransformerParserTests-context.xml index ee594891ff..b20f1dc853 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/ObjectToStringTransformerParserTests-context.xml +++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/ObjectToStringTransformerParserTests-context.xml @@ -23,4 +23,7 @@ + + diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/ObjectToStringTransformerParserTests.java b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/ObjectToStringTransformerParserTests.java index 62b5d6b9ed..d3a24c4618 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/ObjectToStringTransformerParserTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/ObjectToStringTransformerParserTests.java @@ -21,13 +21,14 @@ import static org.junit.Assert.assertNotNull; import org.junit.Test; import org.junit.runner.RunWith; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.integration.Message; import org.springframework.integration.MessageChannel; import org.springframework.integration.core.PollableChannel; +import org.springframework.integration.endpoint.AbstractEndpoint; import org.springframework.integration.message.GenericMessage; +import org.springframework.integration.test.util.TestUtils; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -50,6 +51,8 @@ public class ObjectToStringTransformerParserTests { @Qualifier("output") private PollableChannel output; + @Autowired + private AbstractEndpoint withCharset; @Test public void directChannelWithStringMessage() { @@ -83,9 +86,14 @@ public class ObjectToStringTransformerParserTests { assertEquals("test", result.getPayload()); } + @Test + public void charset() { + assertEquals("FOO", TestUtils.getPropertyValue(this.withCharset, "handler.transformer.charset")); + } private static class TestBean { + @Override public String toString() { return "test"; } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/transformer/ObjectToStringTransformerTests.java b/spring-integration-core/src/test/java/org/springframework/integration/transformer/ObjectToStringTransformerTests.java index 64607464e1..f50a1de359 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/transformer/ObjectToStringTransformerTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/transformer/ObjectToStringTransformerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2013 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. @@ -18,13 +18,16 @@ package org.springframework.integration.transformer; import static org.junit.Assert.assertEquals; -import org.junit.Test; +import java.nio.charset.Charset; +import org.junit.Test; import org.springframework.integration.Message; import org.springframework.integration.message.GenericMessage; /** * @author Mark Fisher + * @author Andrew Cowlin + * @author Gary Russell */ public class ObjectToStringTransformerTests { @@ -42,9 +45,31 @@ public class ObjectToStringTransformerTests { assertEquals("test", result.getPayload()); } + @Test + public void byteArrayPayload() throws Exception { + Transformer transformer = new ObjectToStringTransformer(); + Message result = transformer.transform(new GenericMessage(("foo" + '\u0fff').getBytes("UTF-8"))); + assertEquals("foo" + '\u0fff', result.getPayload()); + } + + @Test + public void byteArrayPayloadCharset() throws Exception { + String defaultCharsetName = Charset.defaultCharset().toString(); + Transformer transformer = new ObjectToStringTransformer(defaultCharsetName); + Message result = transformer.transform(new GenericMessage("foo".getBytes(defaultCharsetName))); + assertEquals("foo", result.getPayload()); + } + + @Test + public void charArrayPayload() { + Transformer transformer = new ObjectToStringTransformer(); + Message result = transformer.transform(new GenericMessage("foo".toCharArray())); + assertEquals("foo", result.getPayload()); + } private static class TestBean { + @Override public String toString() { return "test"; } diff --git a/src/reference/docbook/transformer.xml b/src/reference/docbook/transformer.xml index f0a8e0dd73..57630baf00 100644 --- a/src/reference/docbook/transformer.xml +++ b/src/reference/docbook/transformer.xml @@ -113,6 +113,22 @@ When debugging, this transformer is not typically necessary since the 'logging-channel-adapter' is capable of logging the Message payload. Refer to for more detail. + + + The object-to-string-transformer is very simple; it invokes toString() + on the inbound payload. There are two exceptions to this (since 3.0): if the payload is a char[], + it invokes new String(payload); if the payload is a byte[], it invokes + new String(payload, charset), where charset is "UTF-8" by default. The + charset can be modified by supplying the charset attribute on + the transformer. + + + For more sophistication (such as selection of the charset dynamically, at runtime), you can use + a SpEL expression-based transformer instead; for example: + + ]]> + If you need to serialize an Object to a byte array or deserialize a byte array back into an Object, diff --git a/src/reference/docbook/whats-new.xml b/src/reference/docbook/whats-new.xml index 4fdc765862..d437851637 100644 --- a/src/reference/docbook/whats-new.xml +++ b/src/reference/docbook/whats-new.xml @@ -26,6 +26,13 @@ for at least this number of milliseconds. For more information see . +
+ ObjectToStringTransformer Improvements + + This transformer now correctly transforms byte[] and char[] + payloads to String. For more information see . + +