diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/inbound/HttpRequestHandlingEndpointSupport.java b/spring-integration-http/src/main/java/org/springframework/integration/http/inbound/HttpRequestHandlingEndpointSupport.java index 363b016060..5ccc417177 100644 --- a/spring-integration-http/src/main/java/org/springframework/integration/http/inbound/HttpRequestHandlingEndpointSupport.java +++ b/spring-integration-http/src/main/java/org/springframework/integration/http/inbound/HttpRequestHandlingEndpointSupport.java @@ -19,6 +19,7 @@ package org.springframework.integration.http.inbound; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -54,9 +55,11 @@ import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; +import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartHttpServletRequest; import org.springframework.web.multipart.MultipartResolver; import org.springframework.web.servlet.DispatcherServlet; +import org.springframework.web.util.UriTemplate; /** * Base class for HTTP request handling endpoints. @@ -104,6 +107,8 @@ abstract class HttpRequestHandlingEndpointSupport extends MessagingGatewaySuppor private final boolean expectReply; + private volatile String path; + private volatile boolean extractReplyPayload = true; private volatile MultipartResolver multipartResolver; @@ -140,6 +145,10 @@ abstract class HttpRequestHandlingEndpointSupport extends MessagingGatewaySuppor protected boolean isExpectReply() { return expectReply; } + + public void setPath(String path) { + this.path = path; + } /** * Set the message body converters to use. These converters are used to convert from and to HTTP requests and @@ -244,6 +253,7 @@ abstract class HttpRequestHandlingEndpointSupport extends MessagingGatewaySuppor * Handles the HTTP request by generating a Message and sending it to the request channel. If this gateway's * 'expectReply' property is true, it will also generate a response from the reply Message once received. */ + @SuppressWarnings({ "rawtypes", "unchecked" }) protected final Object doHandleRequest(HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws IOException { try { @@ -252,14 +262,33 @@ abstract class HttpRequestHandlingEndpointSupport extends MessagingGatewaySuppor servletResponse.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED); return null; } + Map uriVariableMappings = null; + // + if (StringUtils.hasText(this.path)){ + UriTemplate template = new UriTemplate(this.path); + uriVariableMappings = template.match(request.getURI().getPath()); + if (logger.isDebugEnabled()){ + logger.debug("Mapped URI variables: " + uriVariableMappings); + } + } + // + + Map headers = this.headerMapper.toHeaders(request.getHeaders()); + Object payload = null; if (this.isReadable(request)) { payload = this.generatePayloadFromRequestBody(request); + headers.putAll(uriVariableMappings); } else { payload = this.convertParameterMap(servletRequest.getParameterMap()); + if (payload instanceof Map){ + for (Object key : uriVariableMappings.keySet()) { + ((Map) payload).put(key, Collections.singletonList(uriVariableMappings.get(key))); + } + } } - Map headers = this.headerMapper.toHeaders(request.getHeaders()); + Message message = MessageBuilder.withPayload(payload).copyHeaders(headers).setHeader( org.springframework.integration.http.HttpHeaders.REQUEST_URL, request.getURI().toString()) .setHeader(org.springframework.integration.http.HttpHeaders.REQUEST_METHOD, diff --git a/spring-integration-http/src/test/java/org/springframework/integration/http/inbound/HttpRequestHandlingMessagingGatewayWithPathMappingTests.java b/spring-integration-http/src/test/java/org/springframework/integration/http/inbound/HttpRequestHandlingMessagingGatewayWithPathMappingTests.java new file mode 100644 index 0000000000..c52ca74e74 --- /dev/null +++ b/spring-integration-http/src/test/java/org/springframework/integration/http/inbound/HttpRequestHandlingMessagingGatewayWithPathMappingTests.java @@ -0,0 +1,80 @@ +/* + * Copyright 2002-2010 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.http.inbound; + +import java.util.Collections; +import java.util.Map; + +import org.junit.Test; +import org.springframework.integration.Message; +import org.springframework.integration.channel.QueueChannel; +import org.springframework.integration.http.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +/** + * @author Oleg Zhurakousky + */ +public class HttpRequestHandlingMessagingGatewayWithPathMappingTests { + + @Test + public void defaultUriVariableMappingWithPOST() throws Exception { + QueueChannel requestChannel = new QueueChannel(); + HttpRequestHandlingMessagingGateway gateway = new HttpRequestHandlingMessagingGateway(false); + gateway.setPath("/fname/{f}/lname/{l}"); + gateway.setRequestChannel(requestChannel); + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setMethod("POST"); + request.setContentType("text/plain"); + request.setParameter("foo", "bar"); + request.setContent("hello".getBytes()); + request.setRequestURI("/fname/bill/lname/clinton"); + MockHttpServletResponse response = new MockHttpServletResponse(); + gateway.handleRequest(request, response); + Message message = requestChannel.receive(0); + assertNotNull(message); + assertEquals("bill", message.getHeaders().get("f")); + assertEquals("clinton", message.getHeaders().get("l")); + } + + @SuppressWarnings("rawtypes") + @Test + public void defaultUriVariableMappingWithGET() throws Exception { + QueueChannel requestChannel = new QueueChannel(); + HttpRequestHandlingMessagingGateway gateway = new HttpRequestHandlingMessagingGateway(false); + gateway.setPath("/fname/{f}/lname/{l}"); + gateway.setRequestChannel(requestChannel); + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setMethod("GET"); + request.setParameter("foo", "bar"); + request.setRequestURI("/fname/bill/lname/clinton"); + MockHttpServletResponse response = new MockHttpServletResponse(); + gateway.handleRequest(request, response); + Message message = requestChannel.receive(0); + assertNotNull(message); + assertNull(message.getHeaders().get("f")); + assertNull(message.getHeaders().get("l")); + Map payload = (Map) message.getPayload(); + assertEquals(Collections.singletonList("bill"), payload.get("f")); + assertEquals(Collections.singletonList("clinton"), payload.get("l")); + } + + +}