INT-4561: deprecate Boon JSON processor support

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

* Remove appropriate tests
* reflect the change in Docs
This commit is contained in:
Artem Bilan
2019-02-22 14:37:39 -05:00
committed by Gary Russell
parent 4f34d922c1
commit f741724656
9 changed files with 22 additions and 121 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2016 the original author or authors.
* Copyright 2014-2019 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.
@@ -47,7 +47,10 @@ import org.springframework.util.ClassUtils;
*
* @author Artem Bilan
* @since 4.1
*
* @deprecated since 5.2. Will be removed in the next version.
*/
@Deprecated
public class BoonJsonObjectMapper extends JsonObjectMapperAdapter<Map<String, Object>, Object>
implements BeanClassLoaderAware {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2019 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.
@@ -31,7 +31,6 @@ import org.springframework.util.ClassUtils;
* @since 3.0
*
* @see Jackson2JsonObjectMapper
* @see BoonJsonObjectMapper
*/
public final class JsonObjectMapperProvider {
@@ -49,12 +48,13 @@ public final class JsonObjectMapperProvider {
* @return the mapper.
* @throws IllegalStateException if an implementation is not available.
*/
@SuppressWarnings("deprecation")
public static JsonObjectMapper<?, ?> newInstance() {
if (JacksonPresent.isJackson2Present()) {
return new Jackson2JsonObjectMapper();
}
else if (boonPresent) {
return new BoonJsonObjectMapper();
return new org.springframework.integration.support.json.BoonJsonObjectMapper();
}
else {
throw new IllegalStateException("Neither jackson-databind.jar, nor boon.jar is present in the classpath.");

View File

@@ -20,7 +20,6 @@ import static org.assertj.core.api.Assertions.assertThat;
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;
@@ -37,9 +36,10 @@ import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonToObjectTransformerTests {
@Test
public void objectPayload() throws Exception {
public void objectPayload() {
JsonToObjectTransformer transformer = new JsonToObjectTransformer(TestPerson.class);
// Since DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES is disabled by default (see Jackson2JsonObjectMapper)
// Since DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES is disabled by default
// (see Jackson2JsonObjectMapper)
// the extra "foo" property is ignored.
String jsonString = "{\"firstName\":\"John\",\"lastName\":\"Doe\",\"age\":42," +
"\"address\":{\"number\":123,\"street\":\"Main Street\"}, \"foo\":\"bar\"}";
@@ -52,28 +52,14 @@ public class JsonToObjectTransformerTests {
}
@Test
public void objectPayloadWithCustomMapper() throws Exception {
public void objectPayloadWithCustomMapper() {
ObjectMapper customMapper = new ObjectMapper();
customMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, Boolean.TRUE);
customMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, Boolean.TRUE);
JsonToObjectTransformer transformer =
new JsonToObjectTransformer(TestPerson.class, new Jackson2JsonObjectMapper(customMapper));
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();
assertThat(person.getFirstName()).isEqualTo("John");
assertThat(person.getLastName()).isEqualTo("Doe");
assertThat(person.getAge()).isEqualTo(42);
assertThat(person.getAddress().toString()).isEqualTo("123 Main Street");
}
@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));
Message<?> message = transformer.transform(new GenericMessage<>(jsonString));
TestPerson person = (TestPerson) message.getPayload();
assertThat(person.getFirstName()).isEqualTo("John");
assertThat(person.getLastName()).isEqualTo("Doe");

View File

@@ -23,7 +23,6 @@ import java.util.List;
import org.junit.Test;
import org.springframework.integration.support.json.BoonJsonObjectMapper;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.GenericMessage;
@@ -40,7 +39,7 @@ public class JsonTransformersSymmetricalTests {
TestPerson person = new TestPerson("John", "Doe", 42);
person.setAddress(new TestAddress(123, "Main Street"));
List<TestPerson> payload = new ArrayList<TestPerson>();
List<TestPerson> payload = new ArrayList<>();
payload.add(person);
ObjectToJsonTransformer objectToJsonTransformer = new ObjectToJsonTransformer();
@@ -52,23 +51,4 @@ public class JsonTransformersSymmetricalTests {
assertThat(((List<?>) result).get(0)).isEqualTo(person);
}
@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).isInstanceOf(List.class);
assertThat(((List<?>) result).get(0)).isEqualTo(person);
}
}

View File

@@ -22,11 +22,6 @@
<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

@@ -18,7 +18,6 @@ package org.springframework.integration.json;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -31,7 +30,6 @@ 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.DefaultMessageBuilderFactory;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.support.json.Jackson2JsonObjectMapper;
@@ -68,9 +66,6 @@ public class ObjectToJsonTransformerParserTests {
@Autowired
private MessageChannel jsonNodeInput;
@Autowired
private MessageChannel boonJsonNodeInput;
@Autowired
private DefaultMessageBuilderFactory defaultMessageBuilderFactory;
@@ -179,29 +174,10 @@ public class ObjectToJsonTransformerParserTests {
assertThat(expression.getValue(evaluationContext, payload, Boolean.class)).isTrue();
}
@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);
assertThat(reply).isNotNull();
Object payload = reply.getPayload();
assertThat(payload).isInstanceOf(Map.class);
assertThat(reply.getHeaders().get(JsonHeaders.TYPE_ID)).isEqualTo(TestPerson.class);
Expression expression = new SpelExpressionParser().parseExpression("[firstName] == 'John' and [age] == 42");
assertThat(expression.getValue(new StandardEvaluationContext(), payload, Boolean.class)).isTrue();
}
static class CustomJsonObjectMapper extends JsonObjectMapperAdapter<Object, Object> {
@Override
public String toJson(Object value) throws Exception {
public String toJson(Object value) {
return "{" + value.toString() + "}";
}

View File

@@ -26,13 +26,8 @@ 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.mapping.support.JsonHeaders;
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;
@@ -196,41 +191,6 @@ public class ObjectToJsonTransformerTests {
assertThat(out.getHeaders().get(JsonHeaders.KEY_TYPE_ID)).isEqualTo(String.class);
}
@Test
public void testBoonJsonObjectMapper() {
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<>(person)).getPayload();
assertThat(result.contains("\"firstName\":\"John\"")).isTrue();
assertThat(result.contains("\"lastName\":\"Doe\"")).isTrue();
assertThat(result.contains("\"age\":42")).isTrue();
Pattern addressPattern = Pattern.compile("(\"address\":\\{.*?\\})");
Matcher matcher = addressPattern.matcher(result);
assertThat(matcher.find()).isTrue();
String addressResult = matcher.group(1);
assertThat(addressResult.contains("\"number\":123")).isTrue();
assertThat(addressResult.contains("\"street\":\"Main Street\"")).isTrue();
}
@Test
public void testBoonJsonObjectMapper_toNode() {
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<>(person)).getPayload();
assertThat(payload).isInstanceOf(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);
assertThat(value).isEqualTo("John: Main Street");
}
@Test
public void testJsonStringAndJsonNode() {
ObjectToJsonTransformer transformer = new ObjectToJsonTransformer(ObjectToJsonTransformer.ResultType.NODE);

View File

@@ -1015,7 +1015,7 @@ The default is `false`.
When `true`, `apply-sequence` is `false` by default.
See also `markers-json` (the next attribute).
<4> When `markers` is true, set this to `true` to have the `FileMarker` objects be converted to a JSON string.
Requires a supported JSON processor library (Jackson or Boon) on the classpath.
Requires a supported JSON processor library (e.g. Jackson) on the classpath.
<5> Set to `false` to disable the inclusion of `sequenceSize` and `sequenceNumber` headers in messages.
The default is `true`, unless `markers` is `true`.
When `true` and `markers` is `true`, the markers are included in the sequencing.
@@ -1049,7 +1049,7 @@ public FileSplitter(boolean iterator, boolean markers, boolean markersJson)
----
====
When `markersJson` is true, the markers are represented as a JSON string, as long as a suitable JSON processor library (such as Jackson or Boon) is on the classpath.
When `markersJson` is true, the markers are represented as a JSON string, as long as a suitable JSON processor library (e.g Jackson) is on the classpath.
Version 5.0 introduced the `firstLineAsHeader` option to specify that the first line of content is a header (such as column names in a CSV file).
The argument passed to this property is the header name under which the first line is carried as a header in the messages emitted for the remaining lines.

View File

@@ -343,16 +343,16 @@ You can provide your own custom `JsonObjectMapper` implementation with appropria
====
Beginning with version 3.0, the `object-mapper` attribute references an instance of a new strategy interface: `JsonObjectMapper`.
This abstraction lets multiple implementations of JSON mappers be used.
Implementations that wrap https://github.com/RichardHightower/boon[Boon] and https://github.com/FasterXML[Jackson 2] are provided, with the version being detected on the classpath.
These classes are `BoonJsonObjectMapper` and `Jackson2JsonObjectMapper`, respectively.
Implementation that wraps https://github.com/FasterXML[Jackson 2] is provided, with the version being detected on the classpath.
The class is `Jackson2JsonObjectMapper`, respectively.
Note, `BoonJsonObjectMapper` was added in version 4.1.
NOTE: The `BoonJsonObjectMapper` is deprecated in 5.2 since the library is out of support.
====
[IMPORTANT]
====
If you have requirements to use both Jackson and Boon in the same application, keep in mind that, before version 3.0, the JSON transformers used only Jackson 1.x.
From 4.1 on, the framework selects Jackson 2 by default, preferring it to the Boon implementation if both are on the classpath.
From 4.1 on, the framework selects Jackson 2 by default.
Jackson 1.x is no longer supported by the framework internally.
However, you can still use it within your code by including the necessary library.
To avoid unexpected issues with JSON mapping features when you use annotations, you may need to apply annotations from both Jackson and Boon on domain classes, as the following example shows:
@@ -373,6 +373,8 @@ public class Thing1 {
----
====
NOTE: The Boon support has been deprecated since version 5.2.
You may wish to consider using a `FactoryBean` or a factory method to create the `JsonObjectMapper` with the required characteristics.
The following example shows how to use such a factory:
@@ -444,7 +446,6 @@ The result node tree representation depends on the implementation of the provide
By default, the `ObjectToJsonTransformer` uses a `Jackson2JsonObjectMapper` and delegates the conversion of the object to the node tree to the `ObjectMapper#valueToTree` method.
The node JSON representation provides efficiency for using the `JsonPropertyAccessor` when the downstream message flow uses SpEL expressions with access to the properties of the JSON data.
See <<spel-property-accessors>> for more information.
When using Boon, the `NODE` representation is a `Map<String, Object>`
Beginning with version 5.1, the `resultType` can be configured as `BYTES` to produce a message with the `byte[]` payload for convenience when working with downstream handlers which operate with this data type.