DefaultOutboundRequestMapper now has an 'extractPayload' boolean flag. It is 'true' by default, but when set to 'false' the Message itself will be serialized and sent as the request body. Also, the default URL is now optional.
This commit is contained in:
@@ -29,6 +29,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.message.MessageDeliveryException;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -39,17 +40,47 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class DefaultOutboundRequestMapper implements OutboundRequestMapper {
|
||||
|
||||
private final URL defaultUrl;
|
||||
private volatile URL defaultUrl;
|
||||
|
||||
private volatile boolean extractPayload = true;
|
||||
|
||||
private volatile String charset = "UTF-8";
|
||||
|
||||
|
||||
/**
|
||||
* Create a DefaultOutboundRequestMapper with no default URL.
|
||||
*/
|
||||
public DefaultOutboundRequestMapper() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a DefaultOutboundRequestMapper with the given default URL.
|
||||
*/
|
||||
public DefaultOutboundRequestMapper(URL defaultUrl) {
|
||||
Assert.notNull(defaultUrl, "default URL must not be null");
|
||||
this.defaultUrl = defaultUrl;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specify the default URL to use when the outbound message does not
|
||||
* contain a value for the {@link HttpHeaders#REQUEST_URL} header.
|
||||
* This default is optional, but if no value is provided, and a Message
|
||||
* does not contain the header, then a MessageDeliveryException will be
|
||||
* thrown at runtime.
|
||||
*/
|
||||
public void setDefaultUrl(URL defaultUrl) {
|
||||
this.defaultUrl = defaultUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify whether the outbound message's payload should be extracted
|
||||
* when preparing the request body. Otherwise the Message instance itself
|
||||
* will be serialized. The default value is <code>true</code>.
|
||||
*/
|
||||
public void setExtractPayload(boolean extractPayload) {
|
||||
this.extractPayload = extractPayload;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the charset name to use for converting String-typed payloads to
|
||||
* bytes. The default is 'UTF-8'.
|
||||
@@ -61,16 +92,26 @@ public class DefaultOutboundRequestMapper implements OutboundRequestMapper {
|
||||
|
||||
public HttpRequest fromMessage(Message<?> message) throws Exception {
|
||||
Assert.notNull(message, "message must not be null");
|
||||
Object payload = message.getPayload();
|
||||
Assert.notNull(payload, "payload must not be null");
|
||||
ByteArrayOutputStream requestBody = new ByteArrayOutputStream();
|
||||
String contentType = null;
|
||||
URL url = this.resolveUrl(message);
|
||||
if (url == null) {
|
||||
throw new MessageDeliveryException(message, "failed to determine a target URL for Message");
|
||||
}
|
||||
Object requestMethodHeader = message.getHeaders().get(HttpHeaders.REQUEST_METHOD);
|
||||
String requestMethod = (requestMethodHeader != null) ?
|
||||
requestMethodHeader.toString().toUpperCase() : "POST";
|
||||
if (this.extractPayload) {
|
||||
Object payload = message.getPayload();
|
||||
Assert.notNull(payload, "payload must not be null");
|
||||
return this.createRequestFromPayload(payload, url, requestMethod);
|
||||
}
|
||||
return this.createRequestFromMessage(message, url, requestMethod);
|
||||
}
|
||||
|
||||
private HttpRequest createRequestFromPayload(Object payload, URL url, String requestMethod) throws Exception {
|
||||
ByteArrayOutputStream requestBody = new ByteArrayOutputStream();
|
||||
String contentType = null;
|
||||
if ("POST".equals(requestMethod) || "PUT".equals(requestMethod)) {
|
||||
contentType = this.writePayloadToRequestBody(payload, requestBody);
|
||||
contentType = this.writeToRequestBody(payload, requestBody);
|
||||
}
|
||||
else {
|
||||
Assert.isTrue(payload instanceof Map,
|
||||
@@ -83,6 +124,14 @@ public class DefaultOutboundRequestMapper implements OutboundRequestMapper {
|
||||
return new DefaultHttpRequest(url, requestMethod, requestBody, contentType);
|
||||
}
|
||||
|
||||
private HttpRequest createRequestFromMessage(Message<?> message, URL url, String requestMethod) throws Exception {
|
||||
Assert.isTrue("POST".equals(requestMethod) || "PUT".equals(requestMethod),
|
||||
"POST or PUT request method is required when the 'extractPayload' value is false.");
|
||||
ByteArrayOutputStream requestBody = new ByteArrayOutputStream();
|
||||
String contentType = this.writeToRequestBody(message, requestBody);
|
||||
return new DefaultHttpRequest(url, requestMethod, requestBody, contentType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a parameter map with String keys and String array values from
|
||||
* the provided map if possible. If the provided map contains any keys that
|
||||
@@ -111,18 +160,18 @@ public class DefaultOutboundRequestMapper implements OutboundRequestMapper {
|
||||
return parameterMap;
|
||||
}
|
||||
|
||||
private String writePayloadToRequestBody(Object payload, ByteArrayOutputStream byteStream) throws Exception {
|
||||
private String writeToRequestBody(Object object, ByteArrayOutputStream byteStream) throws Exception {
|
||||
String contentType = null;
|
||||
if (payload instanceof byte[]) {
|
||||
byteStream.write((byte[]) payload);
|
||||
if (object instanceof byte[]) {
|
||||
byteStream.write((byte[]) object);
|
||||
contentType = "application/octet-stream";
|
||||
}
|
||||
else if (payload instanceof String) {
|
||||
byteStream.write(((String) payload).getBytes(this.charset));
|
||||
else if (object instanceof String) {
|
||||
byteStream.write(((String) object).getBytes(this.charset));
|
||||
contentType = "text/plain; charset=" + this.charset;
|
||||
}
|
||||
else if (payload instanceof Serializable) {
|
||||
byteStream.write(this.serializePayload((Serializable) payload));
|
||||
else if (object instanceof Serializable) {
|
||||
byteStream.write(this.serializeObject((Serializable) object));
|
||||
contentType = "application/x-java-serialized-object";
|
||||
}
|
||||
else {
|
||||
@@ -132,10 +181,10 @@ public class DefaultOutboundRequestMapper implements OutboundRequestMapper {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
private byte[] serializePayload(Serializable payload) throws IOException {
|
||||
private byte[] serializeObject(Serializable object) throws IOException {
|
||||
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
|
||||
ObjectOutputStream objectStream = new ObjectOutputStream(byteStream);
|
||||
objectStream.writeObject(payload);
|
||||
objectStream.writeObject(object);
|
||||
objectStream.flush();
|
||||
objectStream.close();
|
||||
return byteStream.toByteArray();
|
||||
|
||||
@@ -41,9 +41,16 @@ public class HttpOutboundEndpoint extends AbstractReplyProducingMessageHandler {
|
||||
|
||||
private volatile OutboundRequestMapper requestMapper;
|
||||
|
||||
private volatile HttpRequestExecutor requestExecutor;
|
||||
private volatile HttpRequestExecutor requestExecutor = new SimpleHttpRequestExecutor();
|
||||
|
||||
|
||||
/**
|
||||
* Create an HttpOutboundEndpoint with no default URL.
|
||||
*/
|
||||
public HttpOutboundEndpoint() {
|
||||
this.requestMapper = new DefaultOutboundRequestMapper();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an HttpOutboundEndpoint that will send requests to the provided
|
||||
* URL by default. If a Message contains a valid value for the
|
||||
@@ -54,7 +61,6 @@ public class HttpOutboundEndpoint extends AbstractReplyProducingMessageHandler {
|
||||
*/
|
||||
public HttpOutboundEndpoint(URL defaultUrl) {
|
||||
this.requestMapper = new DefaultOutboundRequestMapper(defaultUrl);
|
||||
this.requestExecutor = new SimpleHttpRequestExecutor();
|
||||
}
|
||||
|
||||
|
||||
@@ -83,20 +89,20 @@ public class HttpOutboundEndpoint extends AbstractReplyProducingMessageHandler {
|
||||
try {
|
||||
HttpRequest request = this.requestMapper.fromMessage(requestMessage);
|
||||
HttpResponse response = this.requestExecutor.executeRequest(request);
|
||||
Object replyPayload = this.createReplyPayloadFromResponse(response);
|
||||
replyMessageHolder.set(replyPayload);
|
||||
Object reply = this.createReplyFromResponse(response);
|
||||
replyMessageHolder.set(reply);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new MessageHandlingException(requestMessage,
|
||||
"failed to execute HTTP request", e);
|
||||
throw new MessageHandlingException(requestMessage, "failed to execute HTTP request", e);
|
||||
}
|
||||
}
|
||||
|
||||
private Object createReplyPayloadFromResponse(HttpResponse response) throws Exception {
|
||||
private Object createReplyFromResponse(HttpResponse response) throws Exception {
|
||||
InputStream responseBody = response.getBody();
|
||||
Assert.notNull(responseBody, "received null response body");
|
||||
String contentType = response.getFirstHeader("Content-Type");
|
||||
if (contentType != null && contentType.startsWith("application/x-java-serialized-object")) {
|
||||
// may be either a payload or a serialized Message instance
|
||||
return this.deserializePayload(responseBody);
|
||||
}
|
||||
ByteArrayOutputStream responseByteStream = new ByteArrayOutputStream();
|
||||
|
||||
Reference in New Issue
Block a user