Skip to content

Commit 5874ae8

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 993c6ed commit 5874ae8

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
@@ -57,38 +59,42 @@
5759
public class ObjectToJsonTransformerTests {
5860

5961
@Test
60-
public void simpleStringPayload() throws Exception {
62+
public void simpleStringPayload() {
6163
ObjectToJsonTransformer transformer = new ObjectToJsonTransformer();
62-
String result = (String) transformer.transform(new GenericMessage<String>("foo")).getPayload();
64+
String result = (String) transformer.transform(new GenericMessage<>("foo")).getPayload();
6365
assertEquals("\"foo\"", result);
6466
}
6567

6668
@Test
67-
public void withDefaultContentType() throws Exception {
69+
public void withDefaultContentType() {
6870
ObjectToJsonTransformer transformer = new ObjectToJsonTransformer();
69-
Message<?> result = transformer.transform(new GenericMessage<String>("foo"));
71+
Message<?> result = transformer.transform(new GenericMessage<>("foo"));
7072
assertEquals(ObjectToJsonTransformer.JSON_CONTENT_TYPE, result.getHeaders().get(MessageHeaders.CONTENT_TYPE));
7173
}
7274

7375
@Test
74-
public void withProvidedContentType() throws Exception {
76+
public void withProvidedContentType() {
7577
ObjectToJsonTransformer transformer = new ObjectToJsonTransformer();
76-
Message<?> message = MessageBuilder.withPayload("foo").setHeader(MessageHeaders.CONTENT_TYPE, "text/xml").build();
78+
Message<?> message = MessageBuilder.withPayload("foo")
79+
.setHeader(MessageHeaders.CONTENT_TYPE, "text/xml")
80+
.build();
7781
Message<?> result = transformer.transform(message);
7882
assertEquals("text/xml", result.getHeaders().get(MessageHeaders.CONTENT_TYPE));
7983
}
8084

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

9096
@Test
91-
public void withProvidedContentTypeAsEmptyString() throws Exception {
97+
public void withProvidedContentTypeAsEmptyString() {
9298
ObjectToJsonTransformer transformer = new ObjectToJsonTransformer();
9399
transformer.setContentType("");
94100
Message<?> message = MessageBuilder.withPayload("foo").build();
@@ -97,34 +103,36 @@ public void withProvidedContentTypeAsEmptyString() throws Exception {
97103
}
98104

99105
@Test
100-
public void withProvidedContentTypeAsEmptyStringDoesNotOverride() throws Exception {
106+
public void withProvidedContentTypeAsEmptyStringDoesNotOverride() {
101107
ObjectToJsonTransformer transformer = new ObjectToJsonTransformer();
102108
transformer.setContentType("");
103-
Message<?> message = MessageBuilder.withPayload("foo").setHeader(MessageHeaders.CONTENT_TYPE, "text/xml").build();
109+
Message<?> message = MessageBuilder.withPayload("foo")
110+
.setHeader(MessageHeaders.CONTENT_TYPE, "text/xml")
111+
.build();
104112
Message<?> result = transformer.transform(message);
105113
assertEquals("text/xml", result.getHeaders().get(MessageHeaders.CONTENT_TYPE));
106114
}
107115

108116
@Test(expected = IllegalArgumentException.class)
109-
public void withProvidedContentTypeAsNull() throws Exception {
117+
public void withProvidedContentTypeAsNull() {
110118
ObjectToJsonTransformer transformer = new ObjectToJsonTransformer();
111119
transformer.setContentType(null);
112120
}
113121

114122
@Test
115-
public void simpleIntegerPayload() throws Exception {
123+
public void simpleIntegerPayload() {
116124
ObjectToJsonTransformer transformer = new ObjectToJsonTransformer();
117-
String result = (String) transformer.transform(new GenericMessage<Integer>(123)).getPayload();
125+
String result = (String) transformer.transform(new GenericMessage<>(123)).getPayload();
118126
assertEquals("123", result);
119127
}
120128

121129
@Test
122-
public void objectPayload() throws Exception {
130+
public void objectPayload() {
123131
ObjectToJsonTransformer transformer = new ObjectToJsonTransformer();
124132
TestAddress address = new TestAddress(123, "Main Street");
125133
TestPerson person = new TestPerson("John", "Doe", 42);
126134
person.setAddress(address);
127-
String result = (String) transformer.transform(new GenericMessage<TestPerson>(person)).getPayload();
135+
String result = (String) transformer.transform(new GenericMessage<>(person)).getPayload();
128136
assertTrue(result.contains("\"firstName\":\"John\""));
129137
assertTrue(result.contains("\"lastName\":\"Doe\""));
130138
assertTrue(result.contains("\"age\":42"));
@@ -137,13 +145,13 @@ public void objectPayload() throws Exception {
137145
}
138146

139147
@Test
140-
public void objectPayloadWithCustomObjectMapper() throws Exception {
148+
public void objectPayloadWithCustomObjectMapper() {
141149
ObjectMapper customMapper = new ObjectMapper();
142150
customMapper.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, Boolean.FALSE);
143151
ObjectToJsonTransformer transformer = new ObjectToJsonTransformer(new Jackson2JsonObjectMapper(customMapper));
144152
TestPerson person = new TestPerson("John", "Doe", 42);
145153
person.setAddress(new TestAddress(123, "Main Street"));
146-
String result = (String) transformer.transform(new GenericMessage<TestPerson>(person)).getPayload();
154+
String result = (String) transformer.transform(new GenericMessage<>(person)).getPayload();
147155
assertTrue(result.contains("firstName:\"John\""));
148156
assertTrue(result.contains("lastName:\"Doe\""));
149157
assertTrue(result.contains("age:42"));
@@ -184,11 +192,11 @@ public void collectionOrMapWithNullFirstElement() {
184192
}
185193

186194
@Test
187-
public void testBoonJsonObjectMapper() throws Exception {
195+
public void testBoonJsonObjectMapper() {
188196
ObjectToJsonTransformer transformer = new ObjectToJsonTransformer(new BoonJsonObjectMapper());
189197
TestPerson person = new TestPerson("John", "Doe", 42);
190198
person.setAddress(new TestAddress(123, "Main Street"));
191-
String result = (String) transformer.transform(new GenericMessage<TestPerson>(person)).getPayload();
199+
String result = (String) transformer.transform(new GenericMessage<>(person)).getPayload();
192200
assertTrue(result.contains("\"firstName\":\"John\""));
193201
assertTrue(result.contains("\"lastName\":\"Doe\""));
194202
assertTrue(result.contains("\"age\":42"));
@@ -201,12 +209,12 @@ public void testBoonJsonObjectMapper() throws Exception {
201209
}
202210

203211
@Test
204-
public void testBoonJsonObjectMapper_toNode() throws Exception {
212+
public void testBoonJsonObjectMapper_toNode() {
205213
ObjectToJsonTransformer transformer = new ObjectToJsonTransformer(new BoonJsonObjectMapper(),
206214
ObjectToJsonTransformer.ResultType.NODE);
207215
TestPerson person = new TestPerson("John", "Doe", 42);
208216
person.setAddress(new TestAddress(123, "Main Street"));
209-
Object payload = transformer.transform(new GenericMessage<TestPerson>(person)).getPayload();
217+
Object payload = transformer.transform(new GenericMessage<>(person)).getPayload();
210218
assertThat(payload, instanceOf(Map.class));
211219

212220
SpelExpressionParser parser = new SpelExpressionParser();
@@ -218,4 +226,19 @@ public void testBoonJsonObjectMapper_toNode() throws Exception {
218226
assertEquals("John: Main Street", value);
219227
}
220228

229+
@Test
230+
public void testJsonStringAndJsonNode() {
231+
ObjectToJsonTransformer transformer = new ObjectToJsonTransformer(ObjectToJsonTransformer.ResultType.NODE);
232+
Object result = transformer.transform(new GenericMessage<>("{\"foo\": \"FOO\", \"bar\": 1}")).getPayload();
233+
assertThat(result, instanceOf(ObjectNode.class));
234+
ObjectNode objectNode = (ObjectNode) result;
235+
assertEquals(2, objectNode.size());
236+
assertEquals("FOO", objectNode.path("foo").textValue());
237+
assertEquals(1, objectNode.path("bar").intValue());
238+
239+
result = transformer.transform(new GenericMessage<>("foo")).getPayload();
240+
assertThat(result, instanceOf(TextNode.class));
241+
assertEquals("foo", ((TextNode) result).textValue());
242+
}
243+
221244
}

0 commit comments

Comments
 (0)