diff --git a/spring-integration-core/src/main/java/org/springframework/integration/json/JsonPropertyAccessor.java b/spring-integration-core/src/main/java/org/springframework/integration/json/JsonPropertyAccessor.java index 5c41cfb7a6..3f63e82722 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/json/JsonPropertyAccessor.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/json/JsonPropertyAccessor.java @@ -41,8 +41,8 @@ public class JsonPropertyAccessor implements PropertyAccessor { /** * The kind of types this can work with. */ - private static final Class[] SUPPORTED_CLASSES = - new Class[] { String.class, ObjectNode.class, ArrayNode.class }; + private static final Class[] SUPPORTED_CLASSES = new Class[] { String.class, ToStringFriendlyJsonNode.class, + ObjectNode.class, ArrayNode.class }; // Note: ObjectMapper is thread-safe private ObjectMapper objectMapper = new ObjectMapper(); @@ -59,20 +59,28 @@ public class JsonPropertyAccessor implements PropertyAccessor { return ((index != null && container.has(index)) || container.has(name)); } + private ContainerNode assertContainerNode(JsonNode json) throws AccessException { + if (json instanceof ContainerNode) { + return (ContainerNode) json; + } + else { + throw new AccessException("Can not act on json that is not a ContainerNode: " + + json.getClass().getSimpleName()); + } + } + private ContainerNode asJson(Object target) throws AccessException { if (target instanceof ContainerNode) { return (ContainerNode) target; } + else if (target instanceof ToStringFriendlyJsonNode) { + ToStringFriendlyJsonNode wrapper = (ToStringFriendlyJsonNode) target; + return assertContainerNode(wrapper.node); + } else if (target instanceof String) { try { JsonNode json = this.objectMapper.readTree((String) target); - if (json instanceof ContainerNode) { - return (ContainerNode) json; - } - else { - throw new AccessException("Can not act on json that is not a ContainerNode: " - + json.getClass().getSimpleName()); - } + return assertContainerNode(json); } catch (JsonProcessingException e) { throw new AccessException("Exception while trying to deserialize String", e); @@ -103,10 +111,10 @@ public class JsonPropertyAccessor implements PropertyAccessor { ContainerNode container = asJson(target); Integer index = maybeIndex(name); if (index != null && container.has(index)) { - return new TypedValue(container.get(index)); + return new TypedValue(wrap(container.get(index))); } else { - return new TypedValue(container.get(name)); + return new TypedValue(wrap(container.get(name))); } } @@ -125,4 +133,28 @@ public class JsonPropertyAccessor implements PropertyAccessor { this.objectMapper = objectMapper; } + private ToStringFriendlyJsonNode wrap(JsonNode json) { + return new ToStringFriendlyJsonNode(json); + } + + public static class ToStringFriendlyJsonNode { + private final JsonNode node; + + public ToStringFriendlyJsonNode(JsonNode node) { + this.node = node; + } + + @Override + public String toString() { + if (node.isValueNode()) { + // This is to avoid quotes around a TextNode for example + return node.asText(); + } + else { + return node.toString(); + } + + } + } + } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/json/JsonPropertyAccessorTests.java b/spring-integration-core/src/test/java/org/springframework/integration/json/JsonPropertyAccessorTests.java index 3dfa07b214..c9ddf171ce 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/json/JsonPropertyAccessorTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/json/JsonPropertyAccessorTests.java @@ -25,7 +25,6 @@ import org.springframework.expression.spel.SpelEvaluationException; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; -import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; /** @@ -49,20 +48,20 @@ public class JsonPropertyAccessorTests { @Test public void testSimpleLookup() throws Exception { Object json = mapper.readTree("{\"foo\": \"bar\"}"); - JsonNode actual = evaluate(json, "foo", JsonNode.class); - assertEquals("bar", actual.asText()); + Object actual = evaluate(json, "foo", Object.class); + assertEquals("bar", actual.toString()); } @Test(expected = SpelEvaluationException.class) public void testUnsupportedJsonConstruct() throws Exception { Object json = mapper.readTree("\"foo\""); - evaluate(json, "fizz", JsonNode.class); + evaluate(json, "fizz", Object.class); } @Test(expected = SpelEvaluationException.class) public void testMissingProperty() throws Exception { Object json = mapper.readTree("{\"foo\": \"bar\"}"); - evaluate(json, "fizz", JsonNode.class); + evaluate(json, "fizz", Object.class); } @Test @@ -70,8 +69,8 @@ public class JsonPropertyAccessorTests { Object json = mapper.readTree("[3, 4, 5]"); // JsonNode actual = evaluate("1", json, JsonNode.class); // Does not work // JsonNode actual = evaluate("'1'", json, JsonNode.class); // Does not work - JsonNode actual = evaluate(json, "['1']", JsonNode.class); - assertEquals(4, actual.asInt()); + Object actual = evaluate(json, "['1']", Object.class); + assertEquals("4", actual.toString()); } @Test @@ -79,22 +78,22 @@ public class JsonPropertyAccessorTests { Object json = mapper.readTree("[[3], [4, 5], []]"); // JsonNode actual = evaluate("1.1", json, JsonNode.class); // Does not work // JsonNode actual = evaluate("[1][1]", json, JsonNode.class); // Does not work - JsonNode actual = evaluate(json, "['1']['1']", JsonNode.class); - assertEquals(5, actual.asInt()); + Object actual = evaluate(json, "['1']['1']", Object.class); + assertEquals("5", actual.toString()); } @Test public void testNestedHashConstruct() throws Exception { Object json = mapper.readTree("{\"foo\": {\"bar\": 4, \"fizz\": 5} }"); - JsonNode actual = evaluate(json, "foo.fizz", JsonNode.class); - assertEquals(5, actual.asInt()); + Object actual = evaluate(json, "foo.fizz", Object.class); + assertEquals("5", actual.toString()); } @Test public void testImplicitStringConversion() throws Exception { String json = "{\"foo\": {\"bar\": 4, \"fizz\": 5} }"; - JsonNode actual = evaluate(json, "foo.fizz", JsonNode.class); - assertEquals(5, actual.asInt()); + Object actual = evaluate(json, "foo.fizz", Object.class); + assertEquals("5", actual.toString()); } @Test(expected = SpelEvaluationException.class)