diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/IntegrationNamespaceHandler.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/IntegrationNamespaceHandler.java
index 3af579bc94..96d12dd21a 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/IntegrationNamespaceHandler.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/IntegrationNamespaceHandler.java
@@ -43,6 +43,8 @@ public class IntegrationNamespaceHandler extends AbstractIntegrationNamespaceHan
registerBeanDefinitionParser("object-to-string-transformer", new ObjectToStringTransformerParser());
registerBeanDefinitionParser("object-to-map-transformer", new ObjectToMapTransformerParser());
registerBeanDefinitionParser("map-to-object-transformer", new MapToObjectTransformerParser());
+ registerBeanDefinitionParser("object-to-json-transformer", new ObjectToJsonTransformerParser());
+ registerBeanDefinitionParser("json-to-object-transformer", new JsonToObjectTransformerParser());
registerBeanDefinitionParser("payload-serializing-transformer", new PayloadSerializingTransformerParser());
registerBeanDefinitionParser("payload-deserializing-transformer", new PayloadDeserializingTransformerParser());
registerBeanDefinitionParser("claim-check-in", new ClaimCheckInParser());
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/JsonToObjectTransformerParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/JsonToObjectTransformerParser.java
new file mode 100644
index 0000000000..c0501b9ef2
--- /dev/null
+++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/JsonToObjectTransformerParser.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2002-2010 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.integration.config.xml;
+
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.util.StringUtils;
+import org.w3c.dom.Element;
+
+/**
+ * @author Mark Fisher
+ * @since 2.0
+ */
+public class JsonToObjectTransformerParser extends AbstractTransformerParser {
+
+ @Override
+ protected String getTransformerClassName() {
+ return "org.springframework.integration.json.JsonToObjectTransformer";
+ }
+
+ @Override
+ protected void parseTransformer(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
+ String type = element.getAttribute("type");
+ String objectMapper = element.getAttribute("object-mapper");
+ builder.addConstructorArgValue(type);
+ if (StringUtils.hasText(objectMapper)) {
+ builder.addConstructorArgReference(objectMapper);
+ }
+ }
+
+}
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/ObjectToJsonTransformerParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/ObjectToJsonTransformerParser.java
new file mode 100644
index 0000000000..fb06747da0
--- /dev/null
+++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/ObjectToJsonTransformerParser.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2002-2010 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.integration.config.xml;
+
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.util.StringUtils;
+import org.w3c.dom.Element;
+
+/**
+ * @author Mark Fisher
+ * @since 2.0
+ */
+public class ObjectToJsonTransformerParser extends AbstractTransformerParser {
+
+ @Override
+ protected String getTransformerClassName() {
+ return "org.springframework.integration.json.ObjectToJsonTransformer";
+ }
+
+ @Override
+ protected void parseTransformer(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
+ String objectMapper = element.getAttribute("object-mapper");
+ if (StringUtils.hasText(objectMapper)) {
+ builder.addConstructorArgReference(objectMapper);
+ }
+ }
+
+}
diff --git a/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.0.xsd b/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.0.xsd
index 7066cebf9b..66fe1e2fd9 100644
--- a/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.0.xsd
+++ b/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.0.xsd
@@ -1014,7 +1014,8 @@
-
+
+
@@ -1553,6 +1554,81 @@
+
+
+
+ Defines a Transformer that converts any Object payload to a JSON String.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Reference to a Jackson ObjectMapper instance to be provided optionally
+ if the default ObjectMapper configuration is not desirable.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Defines a Transformer that converts a JSON String to an object.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Reference to a Jackson ObjectMapper instance to be provided optionally
+ if the default ObjectMapper configuration is not desirable.
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/json/JsonToObjectTransformerParserTests-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/json/JsonToObjectTransformerParserTests-context.xml
new file mode 100644
index 0000000000..736862809d
--- /dev/null
+++ b/spring-integration-core/src/test/java/org/springframework/integration/json/JsonToObjectTransformerParserTests-context.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/json/JsonToObjectTransformerParserTests.java b/spring-integration-core/src/test/java/org/springframework/integration/json/JsonToObjectTransformerParserTests.java
new file mode 100644
index 0000000000..1efa1d091b
--- /dev/null
+++ b/spring-integration-core/src/test/java/org/springframework/integration/json/JsonToObjectTransformerParserTests.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2002-2010 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.integration.json;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.codehaus.jackson.JsonParser.Feature;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.integration.Message;
+import org.springframework.integration.MessageChannel;
+import org.springframework.integration.channel.QueueChannel;
+import org.springframework.integration.support.MessageBuilder;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+/**
+ * @author Mark Fisher
+ * @since 2.0
+ */
+@ContextConfiguration
+@RunWith(SpringJUnit4ClassRunner.class)
+public class JsonToObjectTransformerParserTests {
+
+ @Autowired
+ private volatile MessageChannel defaultObjectMapperInput;
+
+ @Autowired
+ private volatile MessageChannel customObjectMapperInput;
+
+
+ @Test
+ public void defaultObjectMapper() {
+ String jsonString = "{\"firstName\":\"John\",\"lastName\":\"Doe\",\"age\":42,\"address\":{\"number\":123,\"street\":\"Main Street\"}}";
+ QueueChannel replyChannel = new QueueChannel();
+ Message message = MessageBuilder.withPayload(jsonString).setReplyChannel(replyChannel).build();
+ this.defaultObjectMapperInput.send(message);
+ Message> reply = replyChannel.receive(0);
+ assertNotNull(reply);
+ assertNotNull(reply.getPayload());
+ assertEquals(TestPerson.class, reply.getPayload().getClass());
+ TestPerson person = (TestPerson) reply.getPayload();
+ assertEquals("John", person.getFirstName());
+ assertEquals("Doe", person.getLastName());
+ assertEquals(42, person.getAge());
+ assertEquals("123 Main Street", person.getAddress().toString());
+ }
+
+ @Test
+ public void customObjectMapper() {
+ String jsonString = "{firstName:'John', lastName:'Doe', age:42, address:{number:123, street:'Main Street'}}";
+ QueueChannel replyChannel = new QueueChannel();
+ Message message = MessageBuilder.withPayload(jsonString).setReplyChannel(replyChannel).build();
+ this.customObjectMapperInput.send(message);
+ Message> reply = replyChannel.receive(0);
+ assertNotNull(reply);
+ assertNotNull(reply.getPayload());
+ assertEquals(TestPerson.class, reply.getPayload().getClass());
+ TestPerson person = (TestPerson) reply.getPayload();
+ assertEquals("John", person.getFirstName());
+ assertEquals("Doe", person.getLastName());
+ assertEquals(42, person.getAge());
+ assertEquals("123 Main Street", person.getAddress().toString());
+ }
+
+
+ static class TestPerson {
+
+ private String firstName;
+
+ private String lastName;
+
+ private int age;
+
+ private TestAddress address;
+
+
+ public String getFirstName() {
+ return this.firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public String getLastName() {
+ return this.lastName;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ public int getAge() {
+ return this.age;
+ }
+
+ public void setAddress(TestAddress address) {
+ this.address = address;
+ }
+
+ public TestAddress getAddress() {
+ return this.address;
+ }
+
+ @Override
+ public String toString() {
+ return "name=" + this.firstName + " " + this.lastName
+ + ", age=" + this.age + ", address=" + this.address;
+ }
+ }
+
+
+ static class TestAddress {
+
+ private int number;
+
+ private String street;
+
+
+ public void setNumber(int number) {
+ this.number = number;
+ }
+
+ public void setStreet(String street) {
+ this.street = street;
+ }
+
+ @Override
+ public String toString() {
+ return this.number + " " + this.street;
+ }
+ }
+
+
+ static class CustomObjectMapper extends ObjectMapper {
+
+ public CustomObjectMapper() {
+ this.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, Boolean.TRUE);
+ this.configure(Feature.ALLOW_SINGLE_QUOTES, Boolean.TRUE);
+ }
+ }
+
+}
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/json/ObjectToJsonTransformerParserTests-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/json/ObjectToJsonTransformerParserTests-context.xml
new file mode 100644
index 0000000000..209b09a2b4
--- /dev/null
+++ b/spring-integration-core/src/test/java/org/springframework/integration/json/ObjectToJsonTransformerParserTests-context.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/json/ObjectToJsonTransformerParserTests.java b/spring-integration-core/src/test/java/org/springframework/integration/json/ObjectToJsonTransformerParserTests.java
new file mode 100644
index 0000000000..73545d8f1d
--- /dev/null
+++ b/spring-integration-core/src/test/java/org/springframework/integration/json/ObjectToJsonTransformerParserTests.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2002-2010 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.integration.json;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.codehaus.jackson.JsonGenerator.Feature;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.integration.Message;
+import org.springframework.integration.MessageChannel;
+import org.springframework.integration.channel.QueueChannel;
+import org.springframework.integration.support.MessageBuilder;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+/**
+ * @author Mark Fisher
+ * @since 2.0
+ */
+@ContextConfiguration
+@RunWith(SpringJUnit4ClassRunner.class)
+public class ObjectToJsonTransformerParserTests {
+
+ @Autowired
+ private volatile MessageChannel defaultObjectMapperInput;
+
+ @Autowired
+ private volatile MessageChannel customObjectMapperInput;
+
+
+ @Test
+ public void defaultObjectMapper() {
+ TestAddress address = new TestAddress();
+ address.setNumber(123);
+ address.setStreet("Main Street");
+ TestPerson person = new TestPerson();
+ person.setFirstName("John");
+ person.setLastName("Doe");
+ person.setAge(42);
+ person.setAddress(address);
+ QueueChannel replyChannel = new QueueChannel();
+ Message message = MessageBuilder.withPayload(person).setReplyChannel(replyChannel).build();
+ this.defaultObjectMapperInput.send(message);
+ Message> reply = replyChannel.receive(0);
+ assertNotNull(reply);
+ assertNotNull(reply.getPayload());
+ assertEquals(String.class, reply.getPayload().getClass());
+ String expected = "{\"address\":{\"number\":123,\"street\":\"Main Street\"},\"firstName\":\"John\",\"lastName\":\"Doe\",\"age\":42}";
+ assertEquals(expected, reply.getPayload());
+ }
+
+ @Test
+ public void customObjectMapper() {
+ TestAddress address = new TestAddress();
+ address.setNumber(123);
+ address.setStreet("Main Street");
+ TestPerson person = new TestPerson();
+ person.setFirstName("John");
+ person.setLastName("Doe");
+ person.setAge(42);
+ person.setAddress(address);
+ QueueChannel replyChannel = new QueueChannel();
+ Message message = MessageBuilder.withPayload(person).setReplyChannel(replyChannel).build();
+ this.customObjectMapperInput.send(message);
+ Message> reply = replyChannel.receive(0);
+ assertNotNull(reply);
+ assertNotNull(reply.getPayload());
+ assertEquals(String.class, reply.getPayload().getClass());
+ String expected = "{address:{number:123,street:\"Main Street\"},firstName:\"John\",lastName:\"Doe\",age:42}";
+ assertEquals(expected, reply.getPayload());
+ }
+
+
+ static class TestPerson {
+
+ private String firstName;
+
+ private String lastName;
+
+ private int age;
+
+ private TestAddress address;
+
+
+ public String getFirstName() {
+ return this.firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public String getLastName() {
+ return this.lastName;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ public int getAge() {
+ return this.age;
+ }
+
+ public void setAddress(TestAddress address) {
+ this.address = address;
+ }
+
+ public TestAddress getAddress() {
+ return this.address;
+ }
+
+ @Override
+ public String toString() {
+ return "name=" + this.firstName + " " + this.lastName
+ + ", age=" + this.age + ", address=" + this.address;
+ }
+ }
+
+
+ static class TestAddress {
+
+ private int number;
+
+ private String street;
+
+
+ public int getNumber() {
+ return this.number;
+ }
+
+ public void setNumber(int number) {
+ this.number = number;
+ }
+
+ public String getStreet() {
+ return this.street;
+ }
+
+ public void setStreet(String street) {
+ this.street = street;
+ }
+
+ @Override
+ public String toString() {
+ return this.number + " " + this.street;
+ }
+ }
+
+
+ static class CustomObjectMapper extends ObjectMapper {
+
+ public CustomObjectMapper() {
+ this.configure(Feature.QUOTE_FIELD_NAMES, Boolean.FALSE);
+ }
+ }
+
+}