From 5f72f5768d56e6c0b83e3e6b12e5f386ddeba896 Mon Sep 17 00:00:00 2001 From: Mark Fisher Date: Thu, 24 Jun 2010 22:52:58 +0000 Subject: [PATCH] INT-1208 --- .../http/DefaultOutboundRequestMapper.java | 15 +++- .../HttpRequestExecutingMessageHandler.java | 78 +++++++------------ .../HttpOutboundChannelAdapterParser.java | 13 +--- .../config/HttpOutboundGatewayParser.java | 7 +- .../DefaultOutboundRequestMapperTests.java | 6 ++ 5 files changed, 51 insertions(+), 68 deletions(-) diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/DefaultOutboundRequestMapper.java b/spring-integration-http/src/main/java/org/springframework/integration/http/DefaultOutboundRequestMapper.java index 6a5c3b2bf1..daf0055de0 100644 --- a/spring-integration-http/src/main/java/org/springframework/integration/http/DefaultOutboundRequestMapper.java +++ b/spring-integration-http/src/main/java/org/springframework/integration/http/DefaultOutboundRequestMapper.java @@ -24,6 +24,7 @@ import javax.xml.transform.Source; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; import org.springframework.integration.core.Message; import org.springframework.util.Assert; @@ -36,6 +37,8 @@ import org.springframework.util.Assert; */ public class DefaultOutboundRequestMapper implements OutboundRequestMapper { + private volatile HttpMethod httpMethod; + private volatile boolean extractPayload = true; private volatile ContentTypeResolver contentTypeResolver = new DefaultContentTypeResolver(); @@ -43,6 +46,13 @@ public class DefaultOutboundRequestMapper implements OutboundRequestMapper { private volatile String charset = "UTF-8"; + /** + * Specify the {@link HttpMethod} that will be used when executing requests. + */ + public void setHttpMethod(HttpMethod httpMethod) { + this.httpMethod = httpMethod; + } + /** * Specify whether the outbound message's payload should be extracted * when preparing the request body. Otherwise the Message instance itself @@ -84,7 +94,10 @@ public class DefaultOutboundRequestMapper implements OutboundRequestMapper { MediaType contentType = (payload instanceof String) ? this.contentTypeResolver.resolveContentType((String) payload, this.charset) : this.contentTypeResolver.resolveContentType(payload); httpHeaders.setContentType(contentType); - return new HttpEntity(requestMessage.getPayload(), httpHeaders); + if (HttpMethod.POST.equals(this.httpMethod) || HttpMethod.PUT.equals(this.httpMethod)) { + return new HttpEntity(requestMessage.getPayload(), httpHeaders); + } + return new HttpEntity(httpHeaders); } private HttpEntity createHttpEntityWithMessageAsBody(Message requestMessage) { diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/HttpRequestExecutingMessageHandler.java b/spring-integration-http/src/main/java/org/springframework/integration/http/HttpRequestExecutingMessageHandler.java index 081ba9355c..8a2f808ded 100755 --- a/spring-integration-http/src/main/java/org/springframework/integration/http/HttpRequestExecutingMessageHandler.java +++ b/spring-integration-http/src/main/java/org/springframework/integration/http/HttpRequestExecutingMessageHandler.java @@ -32,7 +32,6 @@ import org.springframework.integration.handler.AbstractReplyProducingMessageHand import org.springframework.integration.message.MessageBuilder; import org.springframework.integration.message.MessageHandler; import org.springframework.integration.message.MessageHandlingException; -import org.springframework.util.Assert; import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.RestTemplate; @@ -47,13 +46,13 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe private final String uri; - private volatile HttpMethod defaultHttpMethod = HttpMethod.POST; - - private volatile OutboundRequestMapper requestMapper = new DefaultOutboundRequestMapper(); + private volatile HttpMethod httpMethod = HttpMethod.POST; private boolean expectReply = true; - private volatile Class expectedResponseType = Object.class; + private volatile Class expectedResponseType = byte[].class; + + private final DefaultOutboundRequestMapper requestMapper = new DefaultOutboundRequestMapper(); private final RestTemplate restTemplate = new RestTemplate(); @@ -75,12 +74,28 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe /** - * Specify the default {@link HttpMethod}. This will provide a fallback in the case - * that a Message does not contain the HTTP method as a header. If this is not - * explicitly specified, then the default method will be POST. + * Specify the {@link HttpMethod} for requests. The default method will be POST. */ - public void setDefaultHttpMethod(HttpMethod defaultHttpMethod) { - this.defaultHttpMethod = defaultHttpMethod; + public void setHttpMethod(HttpMethod httpMethod) { + this.requestMapper.setHttpMethod(httpMethod); + this.httpMethod = httpMethod; + } + + /** + * 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 true. + */ + public void setExtractPayload(boolean extractPayload) { + this.requestMapper.setExtractPayload(extractPayload); + } + + /** + * Specify the charset name to use for converting String-typed payloads to + * bytes. The default is 'UTF-8'. + */ + public void setCharset(String charset) { + this.requestMapper.setCharset(charset); } /** @@ -123,28 +138,13 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe this.restTemplate.setRequestFactory(requestFactory); } - /** - * Specify the {@link OutboundRequestMapper} implementation to use for mapping a - * {@link Message} into an {@link HttpEntity} when executing an HTTP request. - *

- * If not provided explicitly, the default implementation is {@link DefaultOutboundRequestMapper}. - */ - public void setRequestMapper(OutboundRequestMapper requestMapper) { - Assert.notNull(requestMapper, "requestMapper must not be null"); - this.requestMapper = requestMapper; - } - @Override protected Object handleRequestMessage(Message requestMessage) { try { - HttpMethod httpMethod = this.resolveHttpMethod(requestMessage); // TODO: allow a boolean flag for treating Map as queryParams vs. uriVariables? Map uriVariables = this.determineUriVariables(requestMessage); HttpEntity httpRequest = this.requestMapper.fromMessage(requestMessage); - if (!isWritableRequestMethod(httpMethod) && httpRequest.getBody() != null) { - httpRequest = new HttpEntity(null, httpRequest.getHeaders()); - } - ResponseEntity httpResponse = this.restTemplate.exchange(this.uri, httpMethod, httpRequest, this.expectedResponseType, uriVariables); + ResponseEntity httpResponse = this.restTemplate.exchange(this.uri, this.httpMethod, httpRequest, this.expectedResponseType, uriVariables); if (this.expectReply) { Object responseBody = httpResponse.getBody(); MessageBuilder replyBuilder = (responseBody instanceof Message) ? @@ -161,32 +161,6 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe } } - private boolean isWritableRequestMethod(HttpMethod httpMethod) { - switch (httpMethod) { - case POST: case PUT: return true; - default: return false; - } - } - - private HttpMethod resolveHttpMethod(Message requestMessage) { - HttpMethod httpMethod = null; - Object methodFromMessage = requestMessage.getHeaders().get(HttpHeaders.REQUEST_METHOD); - if (methodFromMessage instanceof HttpMethod) { - httpMethod = (HttpMethod) methodFromMessage; - } - else if (methodFromMessage instanceof String) { - httpMethod = HttpMethod.valueOf((String) methodFromMessage); - } - else if (methodFromMessage != null) { - throw new IllegalArgumentException("expected an HttpMethod enum instance or String for " + - "the REQUEST_METHOD header, but received type: " + methodFromMessage.getClass()); - } - if (httpMethod == null) { - httpMethod = this.defaultHttpMethod; - } - return httpMethod; - } - private Map determineUriVariables(Message requestMessage) { Map uriVariables = new HashMap(); if (requestMessage.getPayload() instanceof Map) { diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/config/HttpOutboundChannelAdapterParser.java b/spring-integration-http/src/main/java/org/springframework/integration/http/config/HttpOutboundChannelAdapterParser.java index eb3ac18004..4e140d9417 100644 --- a/spring-integration-http/src/main/java/org/springframework/integration/http/config/HttpOutboundChannelAdapterParser.java +++ b/spring-integration-http/src/main/java/org/springframework/integration/http/config/HttpOutboundChannelAdapterParser.java @@ -23,7 +23,6 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.integration.config.xml.AbstractOutboundChannelAdapterParser; import org.springframework.integration.config.xml.IntegrationNamespaceUtils; -import org.springframework.util.StringUtils; /** * Parser for the 'outbound-channel-adapter' element of the http namespace. @@ -40,15 +39,9 @@ public class HttpOutboundChannelAdapterParser extends AbstractOutboundChannelAda BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition( PACKAGE_PATH + ".HttpRequestExecutingMessageHandler"); builder.addPropertyValue("expectReply", false); - String url = element.getAttribute("url"); - if (StringUtils.hasText(url)) { - builder.addConstructorArgValue(url); - } - BeanDefinitionBuilder mapperBuilder = BeanDefinitionBuilder.genericBeanDefinition( - PACKAGE_PATH + ".DefaultOutboundRequestMapper"); - IntegrationNamespaceUtils.setValueIfAttributeDefined(mapperBuilder, element, "charset"); - IntegrationNamespaceUtils.setValueIfAttributeDefined(mapperBuilder, element, "extract-payload"); - builder.addPropertyValue("requestMapper", mapperBuilder.getBeanDefinition()); + builder.addConstructorArgValue(element.getAttribute("url")); + IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "charset"); + IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "extract-payload"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "request-factory"); return builder.getBeanDefinition(); } diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/config/HttpOutboundGatewayParser.java b/spring-integration-http/src/main/java/org/springframework/integration/http/config/HttpOutboundGatewayParser.java index 897ec289ac..7172b74a8c 100644 --- a/spring-integration-http/src/main/java/org/springframework/integration/http/config/HttpOutboundGatewayParser.java +++ b/spring-integration-http/src/main/java/org/springframework/integration/http/config/HttpOutboundGatewayParser.java @@ -43,11 +43,8 @@ public class HttpOutboundGatewayParser extends AbstractConsumerEndpointParser { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition( PACKAGE_PATH + ".HttpRequestExecutingMessageHandler"); builder.addConstructorArgValue(element.getAttribute("url")); - BeanDefinitionBuilder mapperBuilder = BeanDefinitionBuilder.genericBeanDefinition( - PACKAGE_PATH + ".DefaultOutboundRequestMapper"); - IntegrationNamespaceUtils.setValueIfAttributeDefined(mapperBuilder, element, "charset"); - IntegrationNamespaceUtils.setValueIfAttributeDefined(mapperBuilder, element, "extract-request-payload", "extractPayload"); - builder.addPropertyValue("requestMapper", mapperBuilder.getBeanDefinition()); + IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "charset"); + IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "extract-request-payload", "extractPayload"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "request-timeout", "sendTimeout"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "request-factory"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "reply-channel", "outputChannel"); diff --git a/spring-integration-http/src/test/java/org/springframework/integration/http/DefaultOutboundRequestMapperTests.java b/spring-integration-http/src/test/java/org/springframework/integration/http/DefaultOutboundRequestMapperTests.java index c7f32239ae..92181f4624 100644 --- a/spring-integration-http/src/test/java/org/springframework/integration/http/DefaultOutboundRequestMapperTests.java +++ b/spring-integration-http/src/test/java/org/springframework/integration/http/DefaultOutboundRequestMapperTests.java @@ -30,6 +30,7 @@ import java.util.Map; import org.junit.Test; import org.springframework.http.HttpEntity; +import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; import org.springframework.integration.core.Message; import org.springframework.integration.message.MessageBuilder; @@ -42,6 +43,7 @@ public class DefaultOutboundRequestMapperTests { @Test public void simpleStringValueFormData() throws Exception { DefaultOutboundRequestMapper mapper = new DefaultOutboundRequestMapper(); + mapper.setHttpMethod(HttpMethod.POST); Map form = new LinkedHashMap(); form.put("a", "1"); form.put("b", "2"); @@ -61,6 +63,7 @@ public class DefaultOutboundRequestMapperTests { @SuppressWarnings("unchecked") public void stringArrayValueFormData() throws Exception { DefaultOutboundRequestMapper mapper = new DefaultOutboundRequestMapper(); + mapper.setHttpMethod(HttpMethod.POST); Map form = new LinkedHashMap(); form.put("a", new String[] { "1", "2", "3" }); form.put("b", "4"); @@ -96,6 +99,7 @@ public class DefaultOutboundRequestMapperTests { @SuppressWarnings("unchecked") public void listValueFormData() throws Exception { DefaultOutboundRequestMapper mapper = new DefaultOutboundRequestMapper(); + mapper.setHttpMethod(HttpMethod.POST); Map form = new LinkedHashMap(); List listA = new ArrayList(); listA.add("1"); @@ -130,6 +134,7 @@ public class DefaultOutboundRequestMapperTests { @SuppressWarnings("unchecked") public void nameOnlyWithNullValues() throws Exception { DefaultOutboundRequestMapper mapper = new DefaultOutboundRequestMapper(); + mapper.setHttpMethod(HttpMethod.POST); Map form = new LinkedHashMap(); form.put("a", null); form.put("b", "foo"); @@ -151,6 +156,7 @@ public class DefaultOutboundRequestMapperTests { @Test public void nonFormDataInMap() throws Exception { DefaultOutboundRequestMapper mapper = new DefaultOutboundRequestMapper(); + mapper.setHttpMethod(HttpMethod.POST); Map form = new LinkedHashMap(); form.put("A", new TestBean()); form.put("B", new TestBean());