Skip to content

Commit ddcfa25

Browse files
artembilangaryrussell
authored andcommitted
INT-4543: JacksonJsonObjectMapper: fix toJsonNode (#2592)
* INT-4543: JacksonJsonObjectMapper: fix toJsonNode JIRA: https://jira.spring.io/browse/INT-4543 When inbound payload is type of `String`, `byte[]`, `File`, `URL`, `InputStream` or `Reader`, we have to use an `ObjectMapper.readTree()` function. For all other types the `valueToTree()` should be used as a fallback **Cherry-pick to 5.0.x** * * Fallback to the `valueToTree()` if not valid JSON * * Fallback to `valueToTree()` only for `String` and `byte[]`
1 parent 1128690 commit ddcfa25

File tree

2 files changed

+78
-26
lines changed

2 files changed

+78
-26
lines changed

spring-integration-core/src/main/java/org/springframework/integration/support/json/Jackson2JsonObjectMapper.java

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2013-2017 the original author or authors.
2+
* Copyright 2013-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -30,6 +30,7 @@
3030
import org.springframework.util.Assert;
3131
import org.springframework.util.ClassUtils;
3232

33+
import com.fasterxml.jackson.core.JsonParseException;
3334
import com.fasterxml.jackson.core.JsonParser;
3435
import com.fasterxml.jackson.databind.DeserializationFeature;
3536
import com.fasterxml.jackson.databind.JavaType;
@@ -91,8 +92,35 @@ public void toJson(Object value, Writer writer) throws Exception {
9192
}
9293

9394
@Override
94-
public JsonNode toJsonNode(Object value) throws Exception {
95-
return this.objectMapper.valueToTree(value);
95+
public JsonNode toJsonNode(Object json) throws Exception {
96+
try {
97+
if (json instanceof String) {
98+
return this.objectMapper.readTree((String) json);
99+
}
100+
else if (json instanceof byte[]) {
101+
return this.objectMapper.readTree((byte[]) json);
102+
}
103+
else if (json instanceof File) {
104+
return this.objectMapper.readTree((File) json);
105+
}
106+
else if (json instanceof URL) {
107+
return this.objectMapper.readTree((URL) json);
108+
}
109+
else if (json instanceof InputStream) {
110+
return this.objectMapper.readTree((InputStream) json);
111+
}
112+
else if (json instanceof Reader) {
113+
return this.objectMapper.readTree((Reader) json);
114+
}
115+
}
116+
catch (JsonParseException e) {
117+
if (!(json instanceof String) && !(json instanceof byte[])) {
118+
throw e;
119+
}
120+
// Otherwise the input might not be valid JSON, fallback to TextNode with ObjectMapper.valueToTree()
121+
}
122+
123+
return this.objectMapper.valueToTree(json);
96124
}
97125

98126
@Override
@@ -137,7 +165,8 @@ protected JavaType extractJavaType(Map<String, Object> javaTypes) throws Excepti
137165
JavaType contentClassType = this.createJavaType(javaTypes, JsonHeaders.CONTENT_TYPE_ID);
138166
if (classType.getKeyType() == null) {
139167
return this.objectMapper.getTypeFactory()
140-
.constructCollectionType((Class<? extends Collection<?>>) classType.getRawClass(), contentClassType);
168+
.constructCollectionType((Class<? extends Collection<?>>) classType.getRawClass(),
169+
contentClassType);
141170
}
142171

143172
JavaType keyClassType = this.createJavaType(javaTypes, JsonHeaders.KEY_TYPE_ID);

spring-integration-core/src/test/java/org/springframework/integration/json/ObjectToJsonTransformerTests.java

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646

4747
import com.fasterxml.jackson.core.JsonGenerator;
4848
import com.fasterxml.jackson.databind.ObjectMapper;
49+
import com.fasterxml.jackson.databind.node.ObjectNode;
50+
import com.fasterxml.jackson.databind.node.TextNode;
4951

5052
/**
5153
* @author Mark Fisher
@@ -58,38 +60,42 @@
5860
public class ObjectToJsonTransformerTests {
5961

6062
@Test
61-
public void simpleStringPayload() throws Exception {
63+
public void simpleStringPayload() {
6264
ObjectToJsonTransformer transformer = new ObjectToJsonTransformer();
63-
String result = (String) transformer.transform(new GenericMessage<String>("foo")).getPayload();
65+
String result = (String) transformer.transform(new GenericMessage<>("foo")).getPayload();
6466
assertEquals("\"foo\"", result);
6567
}
6668

6769
@Test
68-
public void withDefaultContentType() throws Exception {
70+
public void withDefaultContentType() {
6971
ObjectToJsonTransformer transformer = new ObjectToJsonTransformer();
70-
Message<?> result = transformer.transform(new GenericMessage<String>("foo"));
72+
Message<?> result = transformer.transform(new GenericMessage<>("foo"));
7173
assertEquals(ObjectToJsonTransformer.JSON_CONTENT_TYPE, result.getHeaders().get(MessageHeaders.CONTENT_TYPE));
7274
}
7375

7476
@Test
75-
public void withProvidedContentType() throws Exception {
77+
public void withProvidedContentType() {
7678
ObjectToJsonTransformer transformer = new ObjectToJsonTransformer();
77-
Message<?> message = MessageBuilder.withPayload("foo").setHeader(MessageHeaders.CONTENT_TYPE, "text/xml").build();
79+
Message<?> message = MessageBuilder.withPayload("foo")
80+
.setHeader(MessageHeaders.CONTENT_TYPE, "text/xml")
81+
.build();
7882
Message<?> result = transformer.transform(message);
7983
assertEquals("text/xml", result.getHeaders().get(MessageHeaders.CONTENT_TYPE));
8084
}
8185

8286
@Test
83-
public void withProvidedContentTypeWithOverride() throws Exception {
87+
public void withProvidedContentTypeWithOverride() {
8488
ObjectToJsonTransformer transformer = new ObjectToJsonTransformer();
8589
transformer.setContentType(ObjectToJsonTransformer.JSON_CONTENT_TYPE);
86-
Message<?> message = MessageBuilder.withPayload("foo").setHeader(MessageHeaders.CONTENT_TYPE, "text/xml").build();
90+
Message<?> message = MessageBuilder.withPayload("foo")
91+
.setHeader(MessageHeaders.CONTENT_TYPE, "text/xml")
92+
.build();
8793
Message<?> result = transformer.transform(message);
8894
assertEquals(ObjectToJsonTransformer.JSON_CONTENT_TYPE, result.getHeaders().get(MessageHeaders.CONTENT_TYPE));
8995
}
9096

9197
@Test
92-
public void withProvidedContentTypeAsEmptyString() throws Exception {
98+
public void withProvidedContentTypeAsEmptyString() {
9399
ObjectToJsonTransformer transformer = new ObjectToJsonTransformer();
94100
transformer.setContentType("");
95101
Message<?> message = MessageBuilder.withPayload("foo").build();
@@ -98,24 +104,26 @@ public void withProvidedContentTypeAsEmptyString() throws Exception {
98104
}
99105

100106
@Test
101-
public void withProvidedContentTypeAsEmptyStringDoesNotOverride() throws Exception {
107+
public void withProvidedContentTypeAsEmptyStringDoesNotOverride() {
102108
ObjectToJsonTransformer transformer = new ObjectToJsonTransformer();
103109
transformer.setContentType("");
104-
Message<?> message = MessageBuilder.withPayload("foo").setHeader(MessageHeaders.CONTENT_TYPE, "text/xml").build();
110+
Message<?> message = MessageBuilder.withPayload("foo")
111+
.setHeader(MessageHeaders.CONTENT_TYPE, "text/xml")
112+
.build();
105113
Message<?> result = transformer.transform(message);
106114
assertEquals("text/xml", result.getHeaders().get(MessageHeaders.CONTENT_TYPE));
107115
}
108116

109117
@Test(expected = IllegalArgumentException.class)
110-
public void withProvidedContentTypeAsNull() throws Exception {
118+
public void withProvidedContentTypeAsNull() {
111119
ObjectToJsonTransformer transformer = new ObjectToJsonTransformer();
112120
transformer.setContentType(null);
113121
}
114122

115123
@Test
116-
public void simpleIntegerPayload() throws Exception {
124+
public void simpleIntegerPayload() {
117125
ObjectToJsonTransformer transformer = new ObjectToJsonTransformer();
118-
String result = (String) transformer.transform(new GenericMessage<Integer>(123)).getPayload();
126+
String result = (String) transformer.transform(new GenericMessage<>(123)).getPayload();
119127
assertEquals("123", result);
120128
}
121129

@@ -128,12 +136,12 @@ public void simpleIntegerAsBytesPayload() {
128136
}
129137

130138
@Test
131-
public void objectPayload() throws Exception {
139+
public void objectPayload() {
132140
ObjectToJsonTransformer transformer = new ObjectToJsonTransformer();
133141
TestAddress address = new TestAddress(123, "Main Street");
134142
TestPerson person = new TestPerson("John", "Doe", 42);
135143
person.setAddress(address);
136-
String result = (String) transformer.transform(new GenericMessage<TestPerson>(person)).getPayload();
144+
String result = (String) transformer.transform(new GenericMessage<>(person)).getPayload();
137145
assertTrue(result.contains("\"firstName\":\"John\""));
138146
assertTrue(result.contains("\"lastName\":\"Doe\""));
139147
assertTrue(result.contains("\"age\":42"));
@@ -146,13 +154,13 @@ public void objectPayload() throws Exception {
146154
}
147155

148156
@Test
149-
public void objectPayloadWithCustomObjectMapper() throws Exception {
157+
public void objectPayloadWithCustomObjectMapper() {
150158
ObjectMapper customMapper = new ObjectMapper();
151159
customMapper.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, Boolean.FALSE);
152160
ObjectToJsonTransformer transformer = new ObjectToJsonTransformer(new Jackson2JsonObjectMapper(customMapper));
153161
TestPerson person = new TestPerson("John", "Doe", 42);
154162
person.setAddress(new TestAddress(123, "Main Street"));
155-
String result = (String) transformer.transform(new GenericMessage<TestPerson>(person)).getPayload();
163+
String result = (String) transformer.transform(new GenericMessage<>(person)).getPayload();
156164
assertTrue(result.contains("firstName:\"John\""));
157165
assertTrue(result.contains("lastName:\"Doe\""));
158166
assertTrue(result.contains("age:42"));
@@ -193,11 +201,11 @@ public void collectionOrMapWithNullFirstElement() {
193201
}
194202

195203
@Test
196-
public void testBoonJsonObjectMapper() throws Exception {
204+
public void testBoonJsonObjectMapper() {
197205
ObjectToJsonTransformer transformer = new ObjectToJsonTransformer(new BoonJsonObjectMapper());
198206
TestPerson person = new TestPerson("John", "Doe", 42);
199207
person.setAddress(new TestAddress(123, "Main Street"));
200-
String result = (String) transformer.transform(new GenericMessage<TestPerson>(person)).getPayload();
208+
String result = (String) transformer.transform(new GenericMessage<>(person)).getPayload();
201209
assertTrue(result.contains("\"firstName\":\"John\""));
202210
assertTrue(result.contains("\"lastName\":\"Doe\""));
203211
assertTrue(result.contains("\"age\":42"));
@@ -210,12 +218,12 @@ public void testBoonJsonObjectMapper() throws Exception {
210218
}
211219

212220
@Test
213-
public void testBoonJsonObjectMapper_toNode() throws Exception {
221+
public void testBoonJsonObjectMapper_toNode() {
214222
ObjectToJsonTransformer transformer = new ObjectToJsonTransformer(new BoonJsonObjectMapper(),
215223
ObjectToJsonTransformer.ResultType.NODE);
216224
TestPerson person = new TestPerson("John", "Doe", 42);
217225
person.setAddress(new TestAddress(123, "Main Street"));
218-
Object payload = transformer.transform(new GenericMessage<TestPerson>(person)).getPayload();
226+
Object payload = transformer.transform(new GenericMessage<>(person)).getPayload();
219227
assertThat(payload, instanceOf(Map.class));
220228

221229
SpelExpressionParser parser = new SpelExpressionParser();
@@ -227,4 +235,19 @@ public void testBoonJsonObjectMapper_toNode() throws Exception {
227235
assertEquals("John: Main Street", value);
228236
}
229237

238+
@Test
239+
public void testJsonStringAndJsonNode() {
240+
ObjectToJsonTransformer transformer = new ObjectToJsonTransformer(ObjectToJsonTransformer.ResultType.NODE);
241+
Object result = transformer.transform(new GenericMessage<>("{\"foo\": \"FOO\", \"bar\": 1}")).getPayload();
242+
assertThat(result, instanceOf(ObjectNode.class));
243+
ObjectNode objectNode = (ObjectNode) result;
244+
assertEquals(2, objectNode.size());
245+
assertEquals("FOO", objectNode.path("foo").textValue());
246+
assertEquals(1, objectNode.path("bar").intValue());
247+
248+
result = transformer.transform(new GenericMessage<>("foo")).getPayload();
249+
assertThat(result, instanceOf(TextNode.class));
250+
assertEquals("foo", ((TextNode) result).textValue());
251+
}
252+
230253
}

0 commit comments

Comments
 (0)