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:
committed by
Gary Russell
parent
cda4a99023
commit
f84e798272
@@ -19,14 +19,14 @@ package org.springframework.integration.json;
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.integration.mapping.support.JsonHeaders;
|
||||
import org.springframework.integration.support.AbstractIntegrationMessageBuilder;
|
||||
import org.springframework.integration.support.json.JacksonJsonObjectMapperProvider;
|
||||
import org.springframework.integration.support.json.JsonObjectMapperProvider;
|
||||
import org.springframework.integration.support.json.JsonObjectMapper;
|
||||
import org.springframework.integration.transformer.AbstractTransformer;
|
||||
import org.springframework.messaging.Message;
|
||||
|
||||
/**
|
||||
* Transformer implementation that converts a JSON string payload into an instance of the provided target Class.
|
||||
* By default this transformer uses {@linkplain JacksonJsonObjectMapperProvider} factory
|
||||
* By default this transformer uses {@linkplain org.springframework.integration.support.json.JsonObjectMapperProvider} factory
|
||||
* to get an instance of Jackson 1 or Jackson 2 JSON-processor {@linkplain JsonObjectMapper} implementation
|
||||
* depending on the jackson-databind or jackson-mapper-asl libs on the classpath.
|
||||
* Any other {@linkplain JsonObjectMapper} implementation can be provided.
|
||||
@@ -34,7 +34,7 @@ import org.springframework.messaging.Message;
|
||||
* @author Mark Fisher
|
||||
* @author Artem Bilan
|
||||
* @see JsonObjectMapper
|
||||
* @see JacksonJsonObjectMapperProvider
|
||||
* @see org.springframework.integration.support.json.JsonObjectMapperProvider
|
||||
* @since 2.0
|
||||
*/
|
||||
public class JsonToObjectTransformer extends AbstractTransformer implements BeanClassLoaderAware {
|
||||
@@ -57,7 +57,7 @@ public class JsonToObjectTransformer extends AbstractTransformer implements Bean
|
||||
|
||||
public JsonToObjectTransformer(Class<?> targetClass, JsonObjectMapper<?, ?> jsonObjectMapper) {
|
||||
this.targetClass = targetClass;
|
||||
this.jsonObjectMapper = (jsonObjectMapper != null) ? jsonObjectMapper : JacksonJsonObjectMapperProvider.newInstance();
|
||||
this.jsonObjectMapper = (jsonObjectMapper != null) ? jsonObjectMapper : JsonObjectMapperProvider.newInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
package org.springframework.integration.json;
|
||||
|
||||
import org.springframework.integration.support.AbstractIntegrationMessageBuilder;
|
||||
import org.springframework.integration.support.json.JacksonJsonObjectMapperProvider;
|
||||
import org.springframework.integration.support.json.JsonObjectMapperProvider;
|
||||
import org.springframework.integration.support.json.JsonObjectMapper;
|
||||
import org.springframework.integration.transformer.AbstractTransformer;
|
||||
import org.springframework.messaging.Message;
|
||||
@@ -27,7 +27,7 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Transformer implementation that converts a payload instance into a JSON string representation.
|
||||
* By default this transformer uses {@linkplain JacksonJsonObjectMapperProvider} factory
|
||||
* By default this transformer uses {@linkplain org.springframework.integration.support.json.JsonObjectMapperProvider} factory
|
||||
* to get an instance of a Jackson or Jackson 2 JSON-processor {@linkplain JsonObjectMapper} implementation
|
||||
* depending on the jackson-databind or jackson-mapper-asl libs on the classpath.
|
||||
* Any other {@linkplain JsonObjectMapper} implementation can be provided.
|
||||
@@ -56,7 +56,7 @@ public class ObjectToJsonTransformer extends AbstractTransformer {
|
||||
private volatile boolean contentTypeExplicitlySet = false;
|
||||
|
||||
public ObjectToJsonTransformer() {
|
||||
this(JacksonJsonObjectMapperProvider.newInstance());
|
||||
this(JsonObjectMapperProvider.newInstance());
|
||||
}
|
||||
|
||||
public ObjectToJsonTransformer(JsonObjectMapper<?, ?> jsonObjectMapper) {
|
||||
@@ -64,7 +64,7 @@ public class ObjectToJsonTransformer extends AbstractTransformer {
|
||||
}
|
||||
|
||||
public ObjectToJsonTransformer(ResultType resultType) {
|
||||
this(JacksonJsonObjectMapperProvider.newInstance(), resultType);
|
||||
this(JsonObjectMapperProvider.newInstance(), resultType);
|
||||
}
|
||||
|
||||
public ObjectToJsonTransformer(JsonObjectMapper<?, ?> jsonObjectMapper, ResultType resultType) {
|
||||
@@ -113,7 +113,7 @@ public class ObjectToJsonTransformer extends AbstractTransformer {
|
||||
headers.put(MessageHeaders.CONTENT_TYPE, this.contentType);
|
||||
}
|
||||
|
||||
this.jsonObjectMapper.populateJavaTypes(headers, message.getPayload().getClass());
|
||||
this.jsonObjectMapper.populateJavaTypes(headers, message.getPayload());
|
||||
|
||||
messageBuilder.copyHeaders(headers);
|
||||
return messageBuilder.build();
|
||||
|
||||
@@ -104,7 +104,7 @@ public class RecipientListRouter extends AbstractMessageRouter
|
||||
|
||||
/**
|
||||
* Set the recipients for this router.
|
||||
* @param recipientMappings, map contains channelName and expression
|
||||
* @param recipientMappings map contains channelName and expression
|
||||
*/
|
||||
@Override
|
||||
@ManagedAttribute
|
||||
|
||||
@@ -38,7 +38,8 @@ import org.springframework.util.ClassUtils;
|
||||
* @author Artem Bilan
|
||||
* @since 3.0
|
||||
*/
|
||||
public abstract class AbstractJacksonJsonObjectMapper<N, P, J> implements JsonObjectMapper<N, P>, BeanClassLoaderAware {
|
||||
public abstract class AbstractJacksonJsonObjectMapper<N, P, J> extends JsonObjectMapperAdapter<N, P>
|
||||
implements BeanClassLoaderAware {
|
||||
|
||||
protected static final Collection<Class<?>> supportedJsonTypes =
|
||||
Arrays.<Class<?>> asList(String.class, byte[].class, File.class, URL.class, InputStream.class, Reader.class);
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
package org.springframework.integration.support.json;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.PipedReader;
|
||||
import java.io.PipedWriter;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.boon.json.JsonFactory;
|
||||
import org.boon.json.JsonParserAndMapper;
|
||||
import org.boon.json.JsonParserFactory;
|
||||
import org.boon.json.JsonSerializerFactory;
|
||||
import org.boon.json.JsonSlurper;
|
||||
import org.boon.json.ObjectMapper;
|
||||
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.integration.mapping.support.JsonHeaders;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* The Boon (@link https://github.com/RichardHightower/boon) {@link JsonObjectMapper} implementation.
|
||||
*
|
||||
* @author Artem Bilan
|
||||
* @since 4.1
|
||||
*/
|
||||
public class BoonJsonObjectMapper extends JsonObjectMapperAdapter<Map<String, Object>, Object>
|
||||
implements BeanClassLoaderAware {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(BoonJsonObjectMapper.class);
|
||||
|
||||
private static final Collection<Class<?>> supportedJsonTypes =
|
||||
Arrays.<Class<?>>asList(String.class, byte[].class, byte[].class, File.class, InputStream.class, Reader.class);
|
||||
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
private final JsonSlurper slurper = new JsonSlurper();
|
||||
|
||||
private volatile ClassLoader classLoader = ClassUtils.getDefaultClassLoader();
|
||||
|
||||
public BoonJsonObjectMapper() {
|
||||
this.objectMapper = JsonFactory.create();
|
||||
}
|
||||
|
||||
public BoonJsonObjectMapper(JsonParserFactory parserFactory, JsonSerializerFactory serializerFactory) {
|
||||
this.objectMapper = JsonFactory.create(parserFactory, serializerFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toJson(Object value) throws Exception {
|
||||
return this.objectMapper.writeValueAsString(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toJson(Object value, Writer writer) {
|
||||
this.objectMapper.toJson(value, writer);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Map<String, Object> toJsonNode(final Object value) throws Exception {
|
||||
PipedReader in = new PipedReader();
|
||||
final PipedWriter out = new PipedWriter(in);
|
||||
Executors.newSingleThreadExecutor()
|
||||
.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
toJson(value, out);
|
||||
}
|
||||
});
|
||||
return (Map<String, Object>) this.slurper.parse(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T fromJson(Object json, Class<T> type) throws Exception {
|
||||
if (json instanceof String) {
|
||||
return this.objectMapper.readValue((String) json, type);
|
||||
}
|
||||
else if (json instanceof byte[]) {
|
||||
return this.objectMapper.readValue((byte[]) json, type);
|
||||
}
|
||||
else if (json instanceof char[]) {
|
||||
return this.objectMapper.readValue((char[]) json, type);
|
||||
}
|
||||
else if (json instanceof File) {
|
||||
return this.objectMapper.readValue((File) json, type);
|
||||
}
|
||||
else if (json instanceof InputStream) {
|
||||
return this.objectMapper.readValue((InputStream) json, type);
|
||||
}
|
||||
else if (json instanceof Reader) {
|
||||
return this.objectMapper.readValue((Reader) json, type);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("'json' argument must be an instance of: " + supportedJsonTypes
|
||||
+ " , but gotten: " + json.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T fromJson(Object json, Map<String, Object> javaTypes) throws Exception {
|
||||
JsonParserAndMapper parser = this.objectMapper.parser();
|
||||
|
||||
Class<?> classType = this.createJavaType(javaTypes, JsonHeaders.TYPE_ID);
|
||||
|
||||
Class<?> contentClassType = this.createJavaType(javaTypes, JsonHeaders.CONTENT_TYPE_ID);
|
||||
|
||||
Class<?> keyClassType = this.createJavaType(javaTypes, JsonHeaders.KEY_TYPE_ID);
|
||||
|
||||
if (keyClassType != null) {
|
||||
logger.warn("Boon doesn't support the Map 'key' conversion. Will be returned raw Map<String, Object>");
|
||||
if (json instanceof String) {
|
||||
return (T) parser.parseMap((String) json);
|
||||
}
|
||||
else if (json instanceof byte[]) {
|
||||
return (T) parser.parseMap((byte[]) json);
|
||||
}
|
||||
else if (json instanceof char[]) {
|
||||
return (T) parser.parseMap((char[]) json);
|
||||
}
|
||||
else if (json instanceof File) {
|
||||
return (T) parser.parseMap(new FileReader((File) json));
|
||||
}
|
||||
else if (json instanceof InputStream) {
|
||||
return (T) parser.parseMap((InputStream) json);
|
||||
}
|
||||
else if (json instanceof Reader) {
|
||||
return (T) parser.parseMap((Reader) json);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("'json' argument must be an instance of: " + supportedJsonTypes
|
||||
+ " , but gotten: " + json.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
if (contentClassType != null) {
|
||||
if (json instanceof String) {
|
||||
return (T) this.objectMapper.readValue((String) json, (Class<Collection>) classType, contentClassType);
|
||||
}
|
||||
else if (json instanceof byte[]) {
|
||||
return (T) this.objectMapper.readValue((byte[]) json, (Class<Collection>) classType, contentClassType);
|
||||
}
|
||||
else if (json instanceof char[]) {
|
||||
return (T) this.objectMapper.readValue((char[]) json, (Class<Collection>) classType, contentClassType);
|
||||
}
|
||||
else if (json instanceof File) {
|
||||
return (T) this.objectMapper.readValue((File) json, (Class<Collection>) classType, contentClassType);
|
||||
}
|
||||
else if (json instanceof InputStream) {
|
||||
return (T) this.objectMapper.readValue((InputStream) json, (Class<Collection>) classType,
|
||||
contentClassType);
|
||||
}
|
||||
else if (json instanceof Reader) {
|
||||
return (T) this.objectMapper.readValue((Reader) json, (Class<Collection>) classType, contentClassType);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("'json' argument must be an instance of: " + supportedJsonTypes
|
||||
+ " , but gotten: " + json.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
return (T) fromJson(json, classType);
|
||||
}
|
||||
|
||||
protected Class<?> createJavaType(Map<String, Object> javaTypes, String javaTypeKey) throws Exception {
|
||||
Object classValue = javaTypes.get(javaTypeKey);
|
||||
if (classValue instanceof Class<?>) {
|
||||
return (Class<?>) classValue;
|
||||
}
|
||||
else if (classValue != null) {
|
||||
return ClassUtils.forName(classValue.toString(), this.classLoader);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T fromJson(Object parser, Type valueType) throws Exception {
|
||||
throw new UnsupportedOperationException("Boon doesn't support JSON reader parser abstraction");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,14 +25,14 @@ import java.net.URL;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.integration.mapping.support.JsonHeaders;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.JavaType;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import org.springframework.integration.mapping.support.JsonHeaders;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Jackson 2 JSON-processor (@link https://github.com/FasterXML) {@linkplain JsonObjectMapper} implementation.
|
||||
* Delegates <code>toJson</code> and <code>fromJson</code>
|
||||
@@ -90,7 +90,8 @@ public class Jackson2JsonObjectMapper extends AbstractJacksonJsonObjectMapper<Js
|
||||
return this.objectMapper.readValue((Reader) json, type);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("'json' argument must be an instance of: " + supportedJsonTypes);
|
||||
throw new IllegalArgumentException("'json' argument must be an instance of: " + supportedJsonTypes
|
||||
+ " , but gotten: " + json.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,20 +100,6 @@ public class Jackson2JsonObjectMapper extends AbstractJacksonJsonObjectMapper<Js
|
||||
return this.objectMapper.readValue(parser, this.constructType(valueType));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populateJavaTypes(Map<String, Object> map, Class<?> sourceClass) {
|
||||
JavaType javaType = this.objectMapper.constructType(sourceClass);
|
||||
map.put(JsonHeaders.TYPE_ID, javaType.getRawClass());
|
||||
|
||||
if (javaType.isContainerType() && !javaType.isArrayType()) {
|
||||
map.put(JsonHeaders.CONTENT_TYPE_ID, javaType.getContentType().getRawClass());
|
||||
}
|
||||
|
||||
if (javaType.getKeyType() != null) {
|
||||
map.put(JsonHeaders.KEY_TYPE_ID, javaType.getKeyType().getRawClass());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
protected JavaType extractJavaType(Map<String, Object> javaTypes) throws Exception {
|
||||
|
||||
@@ -1,86 +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.support.json;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.codehaus.jackson.JsonFactory;
|
||||
import org.codehaus.jackson.JsonParser;
|
||||
import org.codehaus.jackson.JsonToken;
|
||||
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link JsonInboundMessageMapper.JsonMessageParser} implementation that parses JSON messages
|
||||
* and builds a {@link Message} with the specified payload type from provided {@link JsonInboundMessageMapper}.
|
||||
* Uses Jackson JSON-processor (@link http://jackson.codehaus.org).
|
||||
*
|
||||
* @deprecated Please migrate to {@link Jackson2JsonMessageParser} for Jackson 2.x.
|
||||
*
|
||||
* @author Artem Bilan
|
||||
* @since 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
public class JacksonJsonMessageParser extends AbstractJacksonJsonMessageParser<JsonParser> {
|
||||
|
||||
public JacksonJsonMessageParser() {
|
||||
super(new JacksonJsonObjectMapper());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonParser createJsonParser(String jsonMessage) throws Exception {
|
||||
return new JsonFactory().createJsonParser(jsonMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Message<?> parseWithHeaders(JsonParser parser, String jsonMessage) throws Exception {
|
||||
String error = AbstractJsonInboundMessageMapper.MESSAGE_FORMAT_ERROR + jsonMessage;
|
||||
Assert.isTrue(parser.nextToken() == JsonToken.START_OBJECT, error);
|
||||
Map<String, Object> headers = null;
|
||||
Object payload = null;
|
||||
while (parser.nextToken() != JsonToken.END_OBJECT) {
|
||||
Assert.isTrue(parser.getCurrentToken() == JsonToken.FIELD_NAME, error);
|
||||
boolean isHeadersToken = "headers".equals(parser.getCurrentName());
|
||||
boolean isPayloadToken = "payload".equals(parser.getCurrentName());
|
||||
Assert.isTrue(isHeadersToken || isPayloadToken, error);
|
||||
if (isHeadersToken) {
|
||||
Assert.isTrue(parser.nextToken() == JsonToken.START_OBJECT, error);
|
||||
headers = readHeaders(parser, jsonMessage);
|
||||
}
|
||||
else if (isPayloadToken) {
|
||||
parser.nextToken();
|
||||
payload = this.readPayload(parser, jsonMessage);
|
||||
}
|
||||
}
|
||||
Assert.notNull(headers, error);
|
||||
return this.getMessageBuilderFactory().withPayload(payload).copyHeaders(headers).build();
|
||||
}
|
||||
|
||||
private Map<String, Object> readHeaders(JsonParser parser, String jsonMessage) throws Exception {
|
||||
Map<String, Object> headers = new LinkedHashMap<String, Object>();
|
||||
while (parser.nextToken() != JsonToken.END_OBJECT) {
|
||||
String headerName = parser.getCurrentName();
|
||||
parser.nextToken();
|
||||
Object headerValue = this.readHeader(parser, headerName, jsonMessage);
|
||||
headers.put(headerName, headerValue);
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2014 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.support.json;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.URL;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import org.codehaus.jackson.JsonNode;
|
||||
import org.codehaus.jackson.JsonParser;
|
||||
import org.codehaus.jackson.map.ObjectMapper;
|
||||
import org.codehaus.jackson.type.JavaType;
|
||||
|
||||
import org.springframework.integration.mapping.support.JsonHeaders;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Jackson JSON-processor (@link http://jackson.codehaus.org) {@linkplain JsonObjectMapper} implementation.
|
||||
* Delegates <code>toJson</code> and <code>fromJson</code>
|
||||
* to the {@linkplain org.codehaus.jackson.map.ObjectMapper}
|
||||
*
|
||||
* @deprecated Please migrate to {@link Jackson2JsonObjectMapper} for Jackson 2.x.
|
||||
*
|
||||
* @author Artem Bilan
|
||||
* @since 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
public class JacksonJsonObjectMapper extends AbstractJacksonJsonObjectMapper<JsonNode, JsonParser, JavaType> {
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
public JacksonJsonObjectMapper() {
|
||||
this.objectMapper = new ObjectMapper();
|
||||
}
|
||||
|
||||
public JacksonJsonObjectMapper(ObjectMapper objectMapper) {
|
||||
Assert.notNull(objectMapper, "objectMapper must not be null");
|
||||
this.objectMapper = objectMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toJson(Object value) throws Exception {
|
||||
return this.objectMapper.writeValueAsString(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toJson(Object value, Writer writer) throws Exception {
|
||||
this.objectMapper.writeValue(writer, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonNode toJsonNode(Object value) throws Exception {
|
||||
return this.objectMapper.valueToTree(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T fromJson(JsonParser parser, Type valueType) throws Exception {
|
||||
return this.objectMapper.readValue(parser, this.constructType(valueType));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T> T fromJson(Object json, JavaType type) throws Exception {
|
||||
if (json instanceof String) {
|
||||
return this.objectMapper.readValue((String) json, type);
|
||||
}
|
||||
else if(json instanceof byte[]) {
|
||||
return this.objectMapper.readValue((byte[]) json, type);
|
||||
}
|
||||
else if (json instanceof File) {
|
||||
return this.objectMapper.readValue((File) json, type);
|
||||
}
|
||||
else if (json instanceof URL) {
|
||||
return this.objectMapper.readValue((URL) json, type);
|
||||
}
|
||||
else if (json instanceof InputStream) {
|
||||
return this.objectMapper.readValue((InputStream) json, type);
|
||||
}
|
||||
else if (json instanceof Reader) {
|
||||
return this.objectMapper.readValue((Reader) json, type);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("'json' argument must be an instance of: " + supportedJsonTypes);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populateJavaTypes(Map<String, Object> map, Class<?> sourceClass) {
|
||||
JavaType javaType = this.constructType(sourceClass);
|
||||
map.put(JsonHeaders.TYPE_ID, javaType.getRawClass());
|
||||
|
||||
if (javaType.isContainerType() && !javaType.isArrayType()) {
|
||||
map.put(JsonHeaders.CONTENT_TYPE_ID, javaType.getContentType().getRawClass());
|
||||
}
|
||||
|
||||
if (javaType.getKeyType() != null) {
|
||||
map.put(JsonHeaders.KEY_TYPE_ID, javaType.getKeyType().getRawClass());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JavaType constructType(Type type) {
|
||||
return this.objectMapper.constructType(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
protected JavaType extractJavaType(Map<String, Object> javaTypes) throws Exception {
|
||||
JavaType classType = this.createJavaType(javaTypes, JsonHeaders.TYPE_ID);
|
||||
if (!classType.isContainerType() || classType.isArrayType()) {
|
||||
return classType;
|
||||
}
|
||||
|
||||
JavaType contentClassType = this.createJavaType(javaTypes, JsonHeaders.CONTENT_TYPE_ID);
|
||||
if (classType.getKeyType() == null) {
|
||||
return this.objectMapper.getTypeFactory()
|
||||
.constructCollectionType((Class<? extends Collection<?>>) classType.getRawClass(), contentClassType);
|
||||
}
|
||||
|
||||
JavaType keyClassType = this.createJavaType(javaTypes, JsonHeaders.KEY_TYPE_ID);
|
||||
return this.objectMapper.getTypeFactory()
|
||||
.constructMapType((Class<? extends Map<?, ?>>) classType.getRawClass(), keyClassType, contentClassType);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -38,9 +38,6 @@ public final class JacksonJsonUtils {
|
||||
ClassUtils.isPresent("org.codehaus.jackson.map.ObjectMapper", classLoader) &&
|
||||
ClassUtils.isPresent("org.codehaus.jackson.JsonGenerator", classLoader);
|
||||
|
||||
private static final IllegalStateException NO_JACKSON_LIB_EXCEPTION =
|
||||
new IllegalStateException("Neither jackson-databind.jar, nor jackson-mapper-asl.jar aren't presented in the classpath.");
|
||||
|
||||
public static boolean isJackson2Present() {
|
||||
return jackson2Present;
|
||||
}
|
||||
@@ -49,7 +46,4 @@ public final class JacksonJsonUtils {
|
||||
return jacksonPresent;
|
||||
}
|
||||
|
||||
public static IllegalStateException getNoJacksonLibException() {
|
||||
return NO_JACKSON_LIB_EXCEPTION;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,5 +44,5 @@ public interface JsonObjectMapper<N, P> {
|
||||
|
||||
<T> T fromJson(P parser, Type valueType) throws Exception;
|
||||
|
||||
void populateJavaTypes(Map<String, Object> map, Class<?> sourceClass);
|
||||
void populateJavaTypes(Map<String, Object> map, Object object);
|
||||
}
|
||||
|
||||
@@ -18,8 +18,11 @@ package org.springframework.integration.support.json;
|
||||
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.integration.mapping.support.JsonHeaders;
|
||||
|
||||
/**
|
||||
* Simple {@linkplain JsonObjectMapper} adapter implementation, if there is no need
|
||||
* to provide entire operations implementation.
|
||||
@@ -59,7 +62,15 @@ public abstract class JsonObjectMapperAdapter<N, P> implements JsonObjectMapper<
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populateJavaTypes(Map<String, Object> map, Class<?> sourceClass) {
|
||||
public void populateJavaTypes(Map<String, Object> map, Object object) {
|
||||
map.put(JsonHeaders.TYPE_ID, object.getClass());
|
||||
if (object instanceof Collection && !((Collection) object).isEmpty()) {
|
||||
map.put(JsonHeaders.CONTENT_TYPE_ID, ((Collection) object).iterator().next().getClass());
|
||||
}
|
||||
if (object instanceof Map && !((Map) object).isEmpty()) {
|
||||
map.put(JsonHeaders.CONTENT_TYPE_ID, ((Map) object).values().iterator().next().getClass());
|
||||
map.put(JsonHeaders.KEY_TYPE_ID, ((Map) object).keySet().iterator().next().getClass());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
package org.springframework.integration.support.json;
|
||||
|
||||
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Simple factory to provide {@linkplain Jackson2JsonObjectMapper} or {@linkplain JacksonJsonObjectMapper}
|
||||
* instances dependently of jackson-databind or jackson-mapper-asl libs in the classpath.
|
||||
* Simple factory to provide {@linkplain JsonObjectMapper}
|
||||
* instances dependently of jackson-databind or boon libs in the classpath.
|
||||
* If there are both libs in the classpath, it prefers Jackson 2 JSON-processor implementation.
|
||||
* If there is not any of them, {@linkplain IllegalStateException} will be thrown.
|
||||
*
|
||||
@@ -28,18 +30,25 @@ package org.springframework.integration.support.json;
|
||||
* @since 3.0
|
||||
*
|
||||
* @see Jackson2JsonObjectMapper
|
||||
* @see org.springframework.integration.support.json.BoonJsonObjectMapper
|
||||
*/
|
||||
public final class JacksonJsonObjectMapperProvider {
|
||||
public final class JsonObjectMapperProvider {
|
||||
|
||||
private static final ClassLoader classLoader = JsonObjectMapperProvider.class.getClassLoader();
|
||||
|
||||
private static final boolean boonPresent =
|
||||
ClassUtils.isPresent("org.boon.json.ObjectMapper", classLoader);
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static JsonObjectMapper<?, ?> newInstance() {
|
||||
if (JacksonJsonUtils.isJackson2Present()) {
|
||||
return new Jackson2JsonObjectMapper();
|
||||
}
|
||||
if(JacksonJsonUtils.isJacksonPresent()) {
|
||||
return new JacksonJsonObjectMapper();
|
||||
else if (boonPresent) {
|
||||
return new BoonJsonObjectMapper();
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("Neither jackson-databind.jar, nor boon.jar is present in the classpath.");
|
||||
}
|
||||
throw JacksonJsonUtils.getNoJacksonLibException();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -35,7 +35,7 @@ public class JsonOutboundMessageMapper implements OutboundMessageMapper<String>
|
||||
private volatile JsonObjectMapper<?, ?> jsonObjectMapper;
|
||||
|
||||
public JsonOutboundMessageMapper() {
|
||||
this(JacksonJsonObjectMapperProvider.newInstance());
|
||||
this(JsonObjectMapperProvider.newInstance());
|
||||
}
|
||||
|
||||
public JsonOutboundMessageMapper(JsonObjectMapper<?, ?> jsonObjectMapper) {
|
||||
|
||||
@@ -20,7 +20,7 @@ import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.integration.support.json.JacksonJsonObjectMapperProvider;
|
||||
import org.springframework.integration.support.json.JsonObjectMapperProvider;
|
||||
import org.springframework.integration.support.json.JsonObjectMapper;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -54,7 +54,7 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class ObjectToMapTransformer extends AbstractPayloadTransformer<Object, Map<?,?>> {
|
||||
|
||||
private final JsonObjectMapper<?, ?> jsonObjectMapper = JacksonJsonObjectMapperProvider.newInstance();
|
||||
private final JsonObjectMapper<?, ?> jsonObjectMapper = JsonObjectMapperProvider.newInstance();
|
||||
|
||||
private volatile boolean shouldFlattenKeys = true;
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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"));
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user