INT-2453 content-type and ObjectToJsonTransformer
Added 'content-type' functionality to ObjectToJsonTransformer Added 'content-type' attribute to object-to-json-transformer element Added parser and usage tests to ensure propper overrides (see Mark's last comment here https://github.com/SpringSource/spring-integration/pull/409) Applied required changes to Amqp module to work with standard 'content-type' header INT-2453 polish based on PR comments INT-2453 polished test INT-2453 polished parser
This commit is contained in:
committed by
Gary Russell
parent
c0e03a1666
commit
9656ee70f4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -86,6 +86,8 @@ public final class MessageHeaders implements Map<String, Object>, Serializable {
|
||||
|
||||
public static final String SEQUENCE_DETAILS = "sequenceDetails";
|
||||
|
||||
public static final String CONTENT_TYPE = "content-type";
|
||||
|
||||
|
||||
private final Map<String, Object> headers;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -18,11 +18,13 @@ package org.springframework.integration.config.xml;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.integration.MessageHeaders;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Oleg Zhurakousky
|
||||
* @since 2.0
|
||||
*/
|
||||
public class ObjectToJsonTransformerParser extends AbstractTransformerParser {
|
||||
@@ -38,6 +40,8 @@ public class ObjectToJsonTransformerParser extends AbstractTransformerParser {
|
||||
if (StringUtils.hasText(objectMapper)) {
|
||||
builder.addConstructorArgReference(objectMapper);
|
||||
}
|
||||
if (element.hasAttribute(MessageHeaders.CONTENT_TYPE)){
|
||||
builder.addPropertyValue("contentType", element.getAttribute("content-type"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -13,26 +13,35 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.json;
|
||||
|
||||
import java.io.StringWriter;
|
||||
|
||||
import org.codehaus.jackson.map.ObjectMapper;
|
||||
|
||||
import org.springframework.integration.transformer.AbstractPayloadTransformer;
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.MessageHeaders;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.integration.transformer.AbstractTransformer;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.LinkedCaseInsensitiveMap;
|
||||
|
||||
/**
|
||||
* Transformer implementation that converts a payload instance into a JSON string representation.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @author James Carr
|
||||
* @author Oleg Zhurakousky
|
||||
* @since 2.0
|
||||
*/
|
||||
public class ObjectToJsonTransformer extends AbstractPayloadTransformer<Object, String> {
|
||||
public class ObjectToJsonTransformer extends AbstractTransformer {
|
||||
|
||||
public static final String JSON_CONTENT_TYPE = "application/json";
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
private volatile String contentType = JSON_CONTENT_TYPE;
|
||||
private volatile boolean contentTypeExplicitlySet = false;
|
||||
|
||||
public ObjectToJsonTransformer(ObjectMapper objectMapper) {
|
||||
Assert.notNull(objectMapper, "objectMapper must not be null");
|
||||
@@ -43,11 +52,42 @@ public class ObjectToJsonTransformer extends AbstractPayloadTransformer<Object,
|
||||
this.objectMapper = new ObjectMapper();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the content-type header value
|
||||
*
|
||||
* @param contentType
|
||||
*/
|
||||
public void setContentType(String contentType){
|
||||
// only null assertion is needed since "" is a valid value
|
||||
Assert.notNull(contentType, "'contentType' must not be null");
|
||||
this.contentTypeExplicitlySet = true;
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
protected String transformPayload(Object payload) throws Exception {
|
||||
private String transformPayload(Object payload) throws Exception {
|
||||
StringWriter writer = new StringWriter();
|
||||
this.objectMapper.writeValue(writer, payload);
|
||||
return writer.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
protected Object doTransform(Message<?> message) throws Exception {
|
||||
String payload = this.transformPayload(message.getPayload());
|
||||
MessageBuilder<String> messageBuilder = MessageBuilder.withPayload(payload);
|
||||
|
||||
LinkedCaseInsensitiveMap<Object> headers = new LinkedCaseInsensitiveMap<Object>();
|
||||
headers.putAll(message.getHeaders());
|
||||
|
||||
if (headers.containsKey(MessageHeaders.CONTENT_TYPE)) {
|
||||
if (this.contentTypeExplicitlySet){
|
||||
// override
|
||||
headers.put(MessageHeaders.CONTENT_TYPE, this.contentType);
|
||||
}
|
||||
}
|
||||
else {
|
||||
headers.put(MessageHeaders.CONTENT_TYPE, this.contentType);
|
||||
}
|
||||
messageBuilder.copyHeaders(headers);
|
||||
return messageBuilder.build();
|
||||
}
|
||||
}
|
||||
@@ -268,7 +268,7 @@ public abstract class AbstractHeaderMapper<T> implements RequestReplyHeaderMappe
|
||||
*/
|
||||
private String addPrefixIfNecessary(String prefix, String propertyName) {
|
||||
String headerName = propertyName;
|
||||
if (StringUtils.hasText(prefix) && !headerName.startsWith(prefix)) {
|
||||
if (StringUtils.hasText(prefix) && !headerName.startsWith(prefix) && !headerName.equals(MessageHeaders.CONTENT_TYPE)) {
|
||||
headerName = prefix + propertyName;
|
||||
}
|
||||
return headerName;
|
||||
|
||||
@@ -2017,6 +2017,15 @@
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element ref="poller" />
|
||||
</xsd:choice>
|
||||
<xsd:attribute name="content-type" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Allows you to set 'content-type' Message header. In the case that a content-type header is already present,
|
||||
we will only override that value IF this attribute is explicitely set with
|
||||
content-type value (e.g., content-type="text/xml")
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="object-mapper" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
|
||||
Reference in New Issue
Block a user