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:
committed by
Gary Russell
parent
4f34d922c1
commit
f741724656
@@ -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 {
|
||||
|
||||
|
||||
@@ -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.");
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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() + "}";
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user