diff --git a/org.springframework.integration.http/src/main/java/org/springframework/integration/http/DefaultInboundRequestMapper.java b/org.springframework.integration.http/src/main/java/org/springframework/integration/http/DefaultInboundRequestMapper.java
index ca4f6091c6..587f98e4ac 100644
--- a/org.springframework.integration.http/src/main/java/org/springframework/integration/http/DefaultInboundRequestMapper.java
+++ b/org.springframework.integration.http/src/main/java/org/springframework/integration/http/DefaultInboundRequestMapper.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2009 the original author or authors.
+ * 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.
@@ -20,7 +20,9 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
+import java.io.Serializable;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
@@ -36,6 +38,8 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.integration.core.Message;
import org.springframework.integration.message.MessageBuilder;
import org.springframework.util.FileCopyUtils;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
@@ -47,8 +51,10 @@ import org.springframework.web.multipart.MultipartResolver;
*
* - For a GET request or a POST request with a Content-Type of
* "application/x-www-form-urlencoded", the parameter Map will be copied as the
- * payload. The map's keys will be Strings, and the values will be String arrays
- * as described for {@link ServletRequest#getParameterMap()}.
+ * payload. The map will be an instance of {@link MultiValueMap} where the keys are
+ * Strings and the values are Lists of Strings. Those Lists are populated from the
+ * String array values of the original request parameter Map as described for the
+ * {@link ServletRequest#getParameterMap()} method.
* - If a MultipartResolver has been provided, and a multipart request is
* detected, the multipart file content will be converted to String for any
* "text" content type, or byte arrays otherwise.
@@ -231,8 +237,7 @@ public class DefaultInboundRequestMapper implements InboundRequestMapper {
@SuppressWarnings("unchecked")
private Object createPayloadFromParameterMap(HttpServletRequest request) {
- Map parameterMap = new HashMap(request.getParameterMap());
- return Collections.unmodifiableMap(parameterMap);
+ return new UnmodifiableRequestParameterMap(request.getParameterMap());
}
private Object createPayloadFromTextContent(HttpServletRequest request) throws IOException {
@@ -289,4 +294,61 @@ public class DefaultInboundRequestMapper implements InboundRequestMapper {
builder.setHeader(HttpHeaders.USER_PRINCIPAL, request.getUserPrincipal());
}
+
+ /**
+ * Map class that extends {@link LinkedMultiValueMap} and implements Serializable.
+ * The contents of the map are unmodifiable, so calling any modification operation
+ * (e.g. put, add, or remove) will result in an UnsupportedOperationException.
+ */
+ private static class UnmodifiableRequestParameterMap
+ extends LinkedMultiValueMap implements Serializable {
+
+ UnmodifiableRequestParameterMap(Map parameters) {
+ for (Map.Entry entry : parameters.entrySet()) {
+ super.put(entry.getKey(), Arrays.asList(entry.getValue()));
+ }
+ }
+
+ @Override
+ public void add(String key, String value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void clear() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public List put(String key, List value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void putAll(Map extends String, ? extends List> m) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public List remove(Object key) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void set(String key, String value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setAll(Map values) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Map toSingleValueMap() {
+ return Collections.unmodifiableMap(super.toSingleValueMap());
+ }
+
+ }
+
}
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
index be72970f18..b763ed787f 100644
--- 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2009 the original author or authors.
+ * 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.
@@ -16,30 +16,6 @@
package org.springframework.integration.http;
-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.integration.message.StringMessage;
-import org.springframework.mock.web.MockHttpServletRequest;
-import org.springframework.mock.web.MockHttpServletResponse;
-import org.springframework.web.servlet.View;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-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 static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
@@ -54,6 +30,35 @@ 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.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+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.integration.message.StringMessage;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.servlet.View;
+
/**
* @author Alex Peters
*/
@@ -125,8 +130,8 @@ public class HttpInboundEndpointTests {
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) }));
+ assertThat((List) msgParams.get(key),
+ is(Collections.singletonList(sourceParams.get(key))));
}
return true;
}
@@ -228,10 +233,11 @@ public class HttpInboundEndpointTests {
new IAnswer() {
@SuppressWarnings("unchecked")
public Boolean answer() throws Throwable {
- Map payloadMap = (Map) ((Message) getCurrentArguments()[0]).getPayload();
+ MultiValueMap payloadMap = (MultiValueMap)
+ ((Message) getCurrentArguments()[0]).getPayload();
for (String key : sourceParams.keySet()) {
assertThat(payloadMap.get(key),
- is((Object) new String[] { sourceParams.get(key) }));
+ is(Collections.singletonList(sourceParams.get(key))));
}
return true;
}
@@ -339,6 +345,7 @@ public class HttpInboundEndpointTests {
}
@Test
+ @SuppressWarnings("unchecked")
public void handleRequest_expectReplyWithView_responseDirectedToView() throws Exception {
setupEndpointAsMock(ANY_STRING_PAYLOAD);
View view = createMock(View.class);
diff --git a/org.springframework.integration.http/src/test/java/org/springframework/integration/http/config/HttpInboundChannelAdapterParserTests.java b/org.springframework.integration.http/src/test/java/org/springframework/integration/http/config/HttpInboundChannelAdapterParserTests.java
index 151690b113..323c9e3dec 100644
--- a/org.springframework.integration.http/src/test/java/org/springframework/integration/http/config/HttpInboundChannelAdapterParserTests.java
+++ b/org.springframework.integration.http/src/test/java/org/springframework/integration/http/config/HttpInboundChannelAdapterParserTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2009 the original author or authors.
+ * 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.
@@ -25,7 +25,6 @@ import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.List;
-import java.util.Map;
import javax.servlet.http.HttpServletResponse;
@@ -42,6 +41,7 @@ import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.util.MultiValueMap;
/**
* @author Mark Fisher
@@ -75,12 +75,12 @@ public class HttpInboundChannelAdapterParserTests {
Message> message = requests.receive(0);
assertNotNull(message);
Object payload = message.getPayload();
- assertTrue(payload instanceof Map);
- Map map = (Map) payload;
+ assertTrue(payload instanceof MultiValueMap);
+ MultiValueMap map = (MultiValueMap) payload;
assertEquals(1, map.size());
assertEquals("foo", map.keySet().iterator().next());
- assertEquals(1, map.get("foo").length);
- assertEquals("bar", map.get("foo")[0]);
+ assertEquals(1, map.get("foo").size());
+ assertEquals("bar", map.getFirst("foo"));
}
@Test