INT-3370: Add BoonJsonObjectMapper

JIRA: https://jira.spring.io/browse/INT-3370

* Add `BoonJsonObjectMapper`
* Provide some tests
* Remove deprecations
* Polishing test according removed deprecations
* Change `JsonObjectMapper#populateJavaTypes` to get deal with `payload`, not its `class`,
since we can't (and Jackson's `TypeFactory`, too) determine generic type from `Collection`.
Use `iterators` instead to retrieve the type from the first item.

Conflicts:
	build.gradle
	spring-integration-amqp/src/test/java/org/springframework/integration/amqp/support/DefaultAmqpHeaderMapperTests.java

INT-3370: Polishing according PR comments

* Apply Gary's polishing to the Docs
* Fix `RecipientListRouter` JavaDoc warn
* Fix typo in test name for `UdpUnicastEndToEndTests`
* Fix `RedisQueueOutboundChannelAdapterTests` do not use Jackson 1.x

Final Polish
This commit is contained in:
Artem Bilan
2014-07-15 10:56:07 +03:00
committed by Gary Russell
parent cda4a99023
commit f84e798272
32 changed files with 451 additions and 429 deletions

View File

@@ -33,10 +33,10 @@ import org.junit.Test;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.integration.message.MessageMatcher;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.support.json.JacksonJsonObjectMapperProvider;
import org.springframework.integration.support.json.JsonInboundMessageMapper;
import org.springframework.integration.support.json.JsonInboundMessageMapper.JsonMessageParser;
import org.springframework.integration.support.json.JsonObjectMapper;
import org.springframework.integration.support.json.JsonObjectMapperProvider;
import org.springframework.messaging.Message;
/**
@@ -48,7 +48,7 @@ import org.springframework.messaging.Message;
*/
public abstract class AbstractJsonInboundMessageMapperTests {
private final JsonObjectMapper<?, ?> mapper = JacksonJsonObjectMapperProvider.newInstance();
private final JsonObjectMapper<?, ?> mapper = JsonObjectMapperProvider.newInstance();
@Factory
public static Matcher<Message<?>> sameExceptImmutableHeaders(Message<?> operand) {

View File

@@ -1,33 +0,0 @@
/*
* 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.
* 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 org.springframework.integration.support.json.JsonInboundMessageMapper.JsonMessageParser;
/**
* @author Gary Russell
* @since 3.0
*
*/
@Deprecated
public class JacksonJsonInboundMessageMapperTests extends AbstractJsonInboundMessageMapperTests {
@Override
protected JsonMessageParser<?> getParser() {
return new org.springframework.integration.support.json.JacksonJsonMessageParser();
}
}

View File

@@ -1,33 +0,0 @@
/*
* 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.
* 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 org.springframework.integration.support.json.JsonInboundMessageMapper.JsonMessageParser;
/**
* @author Gary Russell
* @since 3.0
*
*/
@Deprecated
public class JacksonJsonSymmetricalMessageMappingTests extends AbstractJsonSymmetricalMessageMappingTests {
@Override
protected JsonMessageParser<?> getParser() {
return new org.springframework.integration.support.json.JacksonJsonMessageParser();
}
}

View File

@@ -16,16 +16,14 @@
package org.springframework.integration.json;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.*;
import java.io.IOException;
import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.map.ObjectMapper;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import org.springframework.integration.history.MessageHistory;
@@ -112,8 +110,8 @@ public class JsonOutboundMessageMapperTests {
assertEquals(payload, parsedPayload);
}
private TestBean extractJsonPayloadToTestBean(String json) throws JsonParseException, IOException {
JsonParser parser = jsonFactory.createJsonParser(json);
private TestBean extractJsonPayloadToTestBean(String json) throws IOException {
JsonParser parser = jsonFactory.createParser(json);
do {
parser.nextToken();
} while(parser.getCurrentToken() != JsonToken.FIELD_NAME || !parser.getCurrentName().equals("payload"));

View File

@@ -16,16 +16,16 @@
package org.springframework.integration.json;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.springframework.integration.support.json.Jackson2JsonObjectMapper;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.GenericMessage;
import static org.junit.Assert.*;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import org.springframework.integration.support.json.BoonJsonObjectMapper;
import org.springframework.integration.support.json.Jackson2JsonObjectMapper;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.GenericMessage;
/**
* @author Mark Fisher
@@ -62,4 +62,17 @@ public class JsonToObjectTransformerTests {
assertEquals("123 Main Street", person.getAddress().toString());
}
@Test
public void testBoonJsonObjectMapper() throws Exception {
JsonToObjectTransformer transformer = new JsonToObjectTransformer(TestPerson.class, new BoonJsonObjectMapper());
String jsonString = "{\"firstName\":\"John\",\"lastName\":\"Doe\",\"age\":42,\"address\":{\"number\":123,\"street\":\"Main Street\"}}";
Message<?> message = transformer.transform(new GenericMessage<String>(jsonString));
TestPerson person = (TestPerson) message.getPayload();
assertEquals("John", person.getFirstName());
assertEquals("Doe", person.getLastName());
assertEquals(42, person.getAge());
assertEquals("123 Main Street", person.getAddress().toString());
}
}

View File

@@ -16,10 +16,15 @@
package org.springframework.integration.json;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.List;
import org.hamcrest.Matchers;
import org.junit.Test;
import org.springframework.integration.support.json.BoonJsonObjectMapper;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.GenericMessage;
@@ -35,13 +40,35 @@ public class JsonTransformersSymmetricalTests {
TestPerson person = new TestPerson("John", "Doe", 42);
person.setAddress(new TestAddress(123, "Main Street"));
List<TestPerson> payload = new ArrayList<TestPerson>();
payload.add(person);
ObjectToJsonTransformer objectToJsonTransformer = new ObjectToJsonTransformer();
Message<?> jsonMessage = objectToJsonTransformer.transform(new GenericMessage<Object>(person));
Message<?> jsonMessage = objectToJsonTransformer.transform(new GenericMessage<Object>(payload));
JsonToObjectTransformer jsonToObjectTransformer = new JsonToObjectTransformer();
Message<?> result = jsonToObjectTransformer.transform(jsonMessage);
assertEquals(person, result.getPayload());
Object result = jsonToObjectTransformer.transform(jsonMessage).getPayload();
assertThat(result, Matchers.instanceOf(List.class));
assertEquals(person, ((List) result).get(0));
}
@Test
public void testBoonObjectToJson_JsonToObject() {
TestPerson person = new TestPerson("John", "Doe", 42);
person.setAddress(new TestAddress(123, "Main Street"));
List<TestPerson> payload = new ArrayList<TestPerson>();
payload.add(person);
ObjectToJsonTransformer objectToJsonTransformer = new ObjectToJsonTransformer(new BoonJsonObjectMapper());
Message<?> jsonMessage = objectToJsonTransformer.transform(new GenericMessage<Object>(payload));
JsonToObjectTransformer jsonToObjectTransformer = new JsonToObjectTransformer(new BoonJsonObjectMapper());
Object result = jsonToObjectTransformer.transform(jsonMessage).getPayload();
assertThat(result, Matchers.instanceOf(List.class));
assertEquals(person, ((List) result).get(0));
}
}

View File

@@ -18,6 +18,11 @@
<object-to-json-transformer id="jsonNodeTransformer" input-channel="jsonNodeInput" result-type="NODE"/>
<object-to-json-transformer input-channel="boonJsonNodeInput" result-type="NODE"
object-mapper="boonJsonObjectMapper"/>
<beans:bean id="boonJsonObjectMapper" class="org.springframework.integration.support.json.BoonJsonObjectMapper"/>
<beans:bean id="customJsonObjectMapper" class="org.springframework.integration.json.ObjectToJsonTransformerParserTests$CustomJsonObjectMapper"/>
</beans:beans>

View File

@@ -16,15 +16,13 @@
package org.springframework.integration.json;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.*;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.fasterxml.jackson.databind.JsonNode;
import org.hamcrest.Matchers;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -35,6 +33,7 @@ import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.mapping.support.JsonHeaders;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.support.json.Jackson2JsonObjectMapper;
import org.springframework.integration.support.json.JsonObjectMapperAdapter;
@@ -45,8 +44,6 @@ import org.springframework.messaging.MessageHeaders;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.fasterxml.jackson.databind.JsonNode;
/**
* @author Mark Fisher
* @author Oleg Zhurakousky
@@ -70,6 +67,9 @@ public class ObjectToJsonTransformerParserTests {
@Autowired
private volatile MessageChannel jsonNodeInput;
@Autowired
private volatile MessageChannel boonJsonNodeInput;
@Test
public void testContentType(){
ObjectToJsonTransformer transformer =
@@ -165,6 +165,25 @@ public class ObjectToJsonTransformerParserTests {
assertTrue(expression.getValue(evaluationContext, payload, Boolean.class));
}
@Test
public void testBoonNodeResultType() {
TestPerson person = new TestPerson();
person.setFirstName("John");
person.setLastName("Doe");
person.setAge(42);
QueueChannel replyChannel = new QueueChannel();
Message<TestPerson> message = MessageBuilder.withPayload(person).setReplyChannel(replyChannel).build();
this.boonJsonNodeInput.send(message);
Message<?> reply = replyChannel.receive(0);
assertNotNull(reply);
Object payload = reply.getPayload();
assertThat(payload, Matchers.instanceOf(Map.class));
assertEquals(TestPerson.class, reply.getHeaders().get(JsonHeaders.TYPE_ID));
Expression expression = new SpelExpressionParser().parseExpression("[firstName] == 'John' and [age] == 42");
assertTrue(expression.getValue(new StandardEvaluationContext(), payload, Boolean.class));
}
static class CustomJsonObjectMapper extends JsonObjectMapperAdapter<Object, Object> {
@Override

View File

@@ -16,16 +16,24 @@
package org.springframework.integration.json;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.junit.Test;
import org.springframework.context.expression.MapAccessor;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.support.json.BoonJsonObjectMapper;
import org.springframework.integration.support.json.Jackson2JsonObjectMapper;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
@@ -142,4 +150,39 @@ public class ObjectToJsonTransformerTests {
assertTrue(addressResult.contains("street:\"Main Street\""));
}
@Test
public void testBoonJsonObjectMapper() throws Exception {
ObjectToJsonTransformer transformer = new ObjectToJsonTransformer(new BoonJsonObjectMapper());
TestPerson person = new TestPerson("John", "Doe", 42);
person.setAddress(new TestAddress(123, "Main Street"));
String result = (String) transformer.transform(new GenericMessage<TestPerson>(person)).getPayload();
assertTrue(result.contains("\"firstName\":\"John\""));
assertTrue(result.contains("\"lastName\":\"Doe\""));
assertTrue(result.contains("\"age\":42"));
Pattern addressPattern = Pattern.compile("(\"address\":\\{.*?\\})");
Matcher matcher = addressPattern.matcher(result);
assertTrue(matcher.find());
String addressResult = matcher.group(1);
assertTrue(addressResult.contains("\"number\":123"));
assertTrue(addressResult.contains("\"street\":\"Main Street\""));
}
@Test
public void testBoonJsonObjectMapper_toNode() throws Exception {
ObjectToJsonTransformer transformer = new ObjectToJsonTransformer(new BoonJsonObjectMapper(),
ObjectToJsonTransformer.ResultType.NODE);
TestPerson person = new TestPerson("John", "Doe", 42);
person.setAddress(new TestAddress(123, "Main Street"));
Object payload = transformer.transform(new GenericMessage<TestPerson>(person)).getPayload();
assertThat(payload, instanceOf(Map.class));
SpelExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression("firstName + ': ' + address.street");
StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
evaluationContext.addPropertyAccessor(new MapAccessor());
String value = expression.getValue(evaluationContext, payload, String.class);
assertEquals("John: Main Street", value);
}
}

View File

@@ -15,6 +15,8 @@
*/
package org.springframework.integration.transformer;
import static org.junit.Assert.*;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
@@ -23,22 +25,15 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.junit.Test;
import org.springframework.context.expression.MapAccessor;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.messaging.Message;
import org.springframework.integration.support.MessageBuilder;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import org.springframework.messaging.Message;
/**
*
@@ -47,9 +42,10 @@ import static org.junit.Assert.assertNull;
* @since 2.0
*/
public class ObjectToMapTransformerTests {
@SuppressWarnings("unchecked")
@Test
public void testObjectToSpelMapTransformer() throws JsonParseException, JsonMappingException, JsonGenerationException, IOException{
public void testObjectToSpelMapTransformer() throws IOException {
Employee employee = this.buildEmployee();
StandardEvaluationContext context = new StandardEvaluationContext();
context.addPropertyAccessor(new MapAccessor());