diff --git a/org.springframework.integration.http/.classpath b/org.springframework.integration.http/.classpath
index 3120d816da..f3bfa67edd 100644
--- a/org.springframework.integration.http/.classpath
+++ b/org.springframework.integration.http/.classpath
@@ -6,6 +6,8 @@
+
+
diff --git a/org.springframework.integration.http/ivy.xml b/org.springframework.integration.http/ivy.xml
index 699cfe72c3..879dc34200 100644
--- a/org.springframework.integration.http/ivy.xml
+++ b/org.springframework.integration.http/ivy.xml
@@ -21,6 +21,8 @@
+
+
diff --git a/org.springframework.integration.http/src/main/java/org/springframework/integration/http/HttpInboundEndpoint.java b/org.springframework.integration.http/src/main/java/org/springframework/integration/http/HttpInboundEndpoint.java
index 987d663343..485d9261ce 100644
--- a/org.springframework.integration.http/src/main/java/org/springframework/integration/http/HttpInboundEndpoint.java
+++ b/org.springframework.integration.http/src/main/java/org/springframework/integration/http/HttpInboundEndpoint.java
@@ -30,6 +30,7 @@ import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -48,7 +49,9 @@ import org.springframework.web.servlet.View;
* By default the request will be converted to a Message payload according to
* the following rules:
*
- *
For a GET request, the parameter Map will be used as the payload
+ *
For a GET request, the parameter Map will be used as the payload.
+ * The map's keys will be Strings, and the values will be String arrays
+ * as described for {@link ServletRequest#getParameterMap()}
.
*
For other request types, the request body will be used as the payload
* and the type will depend on the Content-Type header value. If it
* begins with "text", a String will be created. Otherwise, the payload
diff --git a/org.springframework.integration.http/src/test/java/org/springframework/integration/http/HttpInboundEndpointTests.java b/org.springframework.integration.http/src/test/java/org/springframework/integration/http/HttpInboundEndpointTests.java
new file mode 100644
index 0000000000..3ef0eb03fe
--- /dev/null
+++ b/org.springframework.integration.http/src/test/java/org/springframework/integration/http/HttpInboundEndpointTests.java
@@ -0,0 +1,394 @@
+/*
+ * Copyright 2002-2009 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;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.getCurrentArguments;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.classextension.EasyMock.createMock;
+import static org.easymock.classextension.EasyMock.replay;
+import static org.easymock.classextension.EasyMock.reset;
+import static org.easymock.classextension.EasyMock.verify;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.junit.Assert.assertThat;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.UnsupportedEncodingException;
+import java.security.Principal;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletResponse;
+
+import org.easymock.IAnswer;
+import org.easymock.classextension.ConstructorArgs;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.springframework.integration.core.Message;
+import org.springframework.integration.core.MessageChannel;
+import org.springframework.integration.core.MessageHeaders;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.web.servlet.View;
+
+/**
+ * @author Alex Peters
+ */
+public class HttpInboundEndpointTests {
+
+ private static final String ANY_ENCODING = "UTF-8";
+
+ private static final String ANY_STRING_PAYLOAD = "any text content..blabla...bla.äöüßß߀€€€";
+
+ private static final byte[] ANY_BINARY_PAYLOAD;
+
+ private final MessageChannel requestChannel = createMock(MessageChannel.class);
+
+ private final MessageChannel replyChannel = createMock(MessageChannel.class);
+
+ private final Object[] allmocks = new Object[] { requestChannel, replyChannel };
+
+ private HttpInboundEndpoint endpoint;
+
+ private MockHttpServletRequest request;
+
+ private MockHttpServletResponse response;
+
+
+ static {
+ try {
+ ANY_BINARY_PAYLOAD = "any binary content..blabla...bla.äöüßß߀€€€".getBytes(ANY_ENCODING);
+ }
+ catch (UnsupportedEncodingException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+
+ @Before
+ public void initializeSample() {
+ endpoint = new HttpInboundEndpoint();
+ endpoint.setRequestChannel(requestChannel);
+ endpoint.setReplyChannel(replyChannel);
+ reset(allmocks);
+ request = new MockHttpServletRequest("GET", "/anyurl");
+ response = new MockHttpServletResponse();
+ response.setCharacterEncoding(ANY_ENCODING);
+ }
+
+
+ @Test
+ public void handleRequest_withDefaultSettingsAndUnsupportedHTTPMethods_returns405()
+ throws ServletException, IOException {
+ String[] httpMethods = { "OPTIONS", "HEAD", "PUT", "DELETE", "TRACE", "CONNECT", "ANY_INVALID" };
+ for (String deniedHttpMethod : httpMethods) {
+ request = new MockHttpServletRequest(deniedHttpMethod, "/anyurl");
+ endpoint.handleRequest(request, response);
+ assertThat("Unexpected result for http method: " + deniedHttpMethod,
+ response.getStatus(),
+ is(HttpServletResponse.SC_METHOD_NOT_ALLOWED));
+ }
+ }
+
+ @Test
+ public void handleRequest_withGETRequest_allReqParametersInMessagePayload()
+ throws ServletException, IOException {
+ final Map sourceParams = addAnyParametersToRequest();
+ expect(requestChannel.send(isA(Message.class))).andAnswer(
+ new IAnswer() {
+ @SuppressWarnings("unchecked")
+ public Boolean answer() throws Throwable {
+ final Map, ?> msgParams = (Map, ?>) ((Message) getCurrentArguments()[0]).getPayload();
+ assertThat(msgParams.size(), is(sourceParams.size()));
+ for (String key : sourceParams.keySet()) {
+ assertThat((String[]) msgParams.get(key),
+ is(new String[] { sourceParams.get(key) }));
+ }
+ return true;
+ }
+ });
+ replay(allmocks);
+ endpoint.handleRequest(request, response);
+ verify(allmocks);
+ }
+
+ @Test
+ public void handleRequest_withEmptyGETRequest_emptyMapIsInMessagePayload()
+ throws ServletException, IOException {
+ expect(requestChannel.send(isA(Message.class))).andAnswer(
+ new IAnswer() {
+ @SuppressWarnings("unchecked")
+ public Boolean answer() throws Throwable {
+ final Map, ?> msgParams = (Map, ?>) ((Message) getCurrentArguments()[0]).getPayload();
+ assertThat(msgParams.size(), is(0));
+ return true;
+ }
+ });
+ replay(allmocks);
+ endpoint.handleRequest(request, response);
+ verify(allmocks);
+ }
+
+ @Test
+ public void handleRequest_withExtractRequestPayloadIsFalse_requestObjectIsInPayload()
+ throws ServletException, IOException {
+ endpoint.setExtractRequestPayload(false);
+ expect(requestChannel.send(isA(Message.class))).andAnswer(
+ new IAnswer() {
+ @SuppressWarnings("unchecked")
+ public Boolean answer() throws Throwable {
+ assertThat(((Message) getCurrentArguments()[0]).getPayload(), is((Object) request));
+ return true;
+ }
+ });
+ replay(allmocks);
+ endpoint.handleRequest(request, response);
+ verify(allmocks);
+ }
+
+ @Test
+ public void handleRequest_RequestHeadersInMsgHeaders()
+ throws ServletException, IOException {
+ final Principal anyPrincipal = createMock(Principal.class);
+ request.setUserPrincipal(anyPrincipal);
+ expect(requestChannel.send(isA(Message.class))).andAnswer(
+ new IAnswer() {
+ @SuppressWarnings("unchecked")
+ public Boolean answer() throws Throwable {
+ MessageHeaders headers = ((Message) getCurrentArguments()[0]).getHeaders();
+ assertThat(headers.get(HttpHeaders.REQUEST_METHOD),
+ is((Object) "GET"));
+ assertThat(headers.get(HttpHeaders.REQUEST_URL),
+ is((Object) "http://localhost:80/anyurl"));
+ assertThat(headers.get(HttpHeaders.USER_PRINCIPAL),
+ is((Object) anyPrincipal));
+ return true;
+ }
+ });
+ replay(allmocks);
+ endpoint.handleRequest(request, response);
+ verify(allmocks);
+ }
+
+ @Test
+ public void handleRequest_withPOSTRequestAndTextContent_sameInMessagePayload()
+ throws ServletException, IOException {
+ final String characterEncoding = ANY_ENCODING;
+ addRequestContent("POST", "text/plain", characterEncoding,
+ ANY_STRING_PAYLOAD.getBytes(characterEncoding));
+ expect(requestChannel.send(isA(Message.class))).andAnswer(
+ new IAnswer() {
+ @SuppressWarnings("unchecked")
+ public Boolean answer() throws Throwable {
+ assertThat((String) ((Message) getCurrentArguments()[0]).getPayload(),
+ is(ANY_STRING_PAYLOAD));
+ return true;
+ }
+ });
+ replay(allmocks);
+ endpoint.handleRequest(request, response);
+ verify(allmocks);
+ }
+
+ @Test
+ public void handleRequest_withPOSTRequestAndParamsOnly_sameInMessageHeader()
+ throws ServletException, IOException {
+ addRequestContent("POST", "text/plain", ANY_ENCODING, new byte[0]);
+ final Map sourceParams = addAnyParametersToRequest();
+ request.setParameters(sourceParams);
+ expect(requestChannel.send(isA(Message.class))).andAnswer(
+ new IAnswer() {
+ @SuppressWarnings("unchecked")
+ public Boolean answer() throws Throwable {
+ MessageHeaders headers = ((Message) getCurrentArguments()[0]).getHeaders();
+ for (String key : sourceParams.keySet()) {
+ assertThat(headers.get(key),
+ is((Object) new String[] { sourceParams.get(key) }));
+ }
+ return true;
+ }
+ });
+ replay(allmocks);
+ endpoint.handleRequest(request, response);
+ verify(allmocks);
+ }
+
+ @Test
+ public void handleRequest_withEmptyPOSTRequest_emptyStringAsPayload()
+ throws ServletException, IOException {
+ addRequestContent("POST", "text/plain", null, new byte[0]);
+ expect(requestChannel.send(isA(Message.class))).andAnswer(
+ new IAnswer() {
+ @SuppressWarnings("unchecked")
+ public Boolean answer() throws Throwable {
+ assertThat((String) ((Message) getCurrentArguments()[0]).getPayload(), is(""));
+ return true;
+ }
+ });
+ replay(allmocks);
+ endpoint.handleRequest(request, response);
+ verify(allmocks);
+ }
+
+ @Test
+ public void handleRequest_withPOSTRequestAndBinaryContent_sameInMessagePayload()
+ throws ServletException, IOException {
+ addRequestContent("POST", "", ANY_ENCODING, ANY_BINARY_PAYLOAD);
+ expect(requestChannel.send(isA(Message.class))).andAnswer(
+ new IAnswer() {
+ @SuppressWarnings("unchecked")
+ public Boolean answer() throws Throwable {
+ assertThat((byte[]) ((Message) getCurrentArguments()[0]).getPayload(),
+ is(ANY_BINARY_PAYLOAD));
+ return true;
+ }
+ });
+ replay(allmocks);
+ endpoint.handleRequest(request, response);
+ verify(allmocks);
+ }
+
+ @Test
+ public void handleRequest_withPOSTRequestEmptyContentLenght_return411()
+ throws ServletException, IOException {
+ addRequestContent("POST", "", ANY_ENCODING, null);
+ endpoint.handleRequest(request, response);
+ assertThat(response.getStatus(), is(HttpServletResponse.SC_LENGTH_REQUIRED));
+ }
+
+ @Test
+ public void handleRequest_withoutReplyMessage_return200()
+ throws ServletException, IOException {
+ expect(requestChannel.send(isA(Message.class))).andReturn(true);
+ replay(allmocks);
+ endpoint.handleRequest(request, response);
+ assertThat(response.getStatus(), is(HttpServletResponse.SC_OK));
+ }
+
+ @Test
+ public void handleRequest_replyWithTextPayload_textAsRespContent()
+ throws ServletException, IOException {
+ setupEndpointAsMock(ANY_STRING_PAYLOAD);
+ replay(allmocks);
+ endpoint.handleRequest(request, response);
+ assertThat(response.getContentAsString(), is(ANY_STRING_PAYLOAD));
+ verify(allmocks);
+ }
+
+ @Test
+ public void handleRequest_replyWithBytePayload_bytesAsRespContent()
+ throws ServletException, IOException {
+ setupEndpointAsMock(ANY_BINARY_PAYLOAD);
+ replay(allmocks);
+ endpoint.handleRequest(request, response);
+ assertThat(response.getContentAsByteArray(), is(ANY_BINARY_PAYLOAD));
+ verify(allmocks);
+ }
+
+ @Test
+ public void handleRequest_replyWithSerializablePayload_serializableAsRespContent()
+ throws ServletException, IOException, ClassNotFoundException {
+ Date obj = new Date();
+ setupEndpointAsMock(obj);
+ replay(allmocks);
+ endpoint.handleRequest(request, response);
+ byte[] content = response.getContentAsByteArray();
+ Object deserializedObj = new ObjectInputStream(
+ new ByteArrayInputStream(content)).readObject();
+ assertThat(deserializedObj, is(Date.class));
+ assertThat((Date) deserializedObj, is(obj));
+ verify(allmocks);
+ }
+
+ @Test(expected = ServletException.class)
+ public void handleRequest_replyWithNonSerializablePayload_exceptionThrown()
+ throws ServletException, IOException, ClassNotFoundException {
+ Object obj = new Object();
+ setupEndpointAsMock(obj);
+ replay(allmocks);
+ endpoint.handleRequest(request, response);
+ verify(allmocks);
+ }
+
+ @Test
+ public void handleRequest_expectReplyWithView_responseDirectedToView() throws Exception {
+ setupEndpointAsMock(ANY_STRING_PAYLOAD);
+ View view = createMock(View.class);
+ view.render(isA(Map.class), eq(request), eq(response));
+ expectLastCall().andAnswer(new IAnswer