SPR-6021 - Allow for using MultiValueMap in GET request for mapping multiple request params
This commit is contained in:
parent
53eb612a68
commit
2288b2523e
|
|
@ -35,6 +35,7 @@ import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.Iterator;
|
||||||
import javax.servlet.ServletConfig;
|
import javax.servlet.ServletConfig;
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
|
|
@ -80,6 +81,7 @@ import org.springframework.ui.format.date.DateFormatter;
|
||||||
import org.springframework.ui.format.support.GenericFormatterRegistry;
|
import org.springframework.ui.format.support.GenericFormatterRegistry;
|
||||||
import org.springframework.util.SerializationTestUtils;
|
import org.springframework.util.SerializationTestUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.util.MultiValueMap;
|
||||||
import org.springframework.validation.BindingResult;
|
import org.springframework.validation.BindingResult;
|
||||||
import org.springframework.validation.Errors;
|
import org.springframework.validation.Errors;
|
||||||
import org.springframework.validation.FieldError;
|
import org.springframework.validation.FieldError;
|
||||||
|
|
@ -1146,6 +1148,25 @@ public class ServletAnnotationControllerTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void requestParamMap() throws Exception {
|
||||||
|
initServlet(RequestParamMapController.class);
|
||||||
|
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/map");
|
||||||
|
request.addParameter("key1", "value1");
|
||||||
|
request.addParameter("key2", new String[]{"value21", "value22"});
|
||||||
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
|
|
||||||
|
servlet.service(request, response);
|
||||||
|
assertEquals("key1=value1,key2=value21", response.getContentAsString());
|
||||||
|
|
||||||
|
request.setRequestURI("/multiValueMap");
|
||||||
|
response = new MockHttpServletResponse();
|
||||||
|
|
||||||
|
servlet.service(request, response);
|
||||||
|
assertEquals("key1=[value1],key2=[value21,value22]", response.getContentAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Controllers
|
* Controllers
|
||||||
|
|
@ -1943,5 +1964,40 @@ public class ServletAnnotationControllerTests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public static class RequestParamMapController {
|
||||||
|
|
||||||
|
@RequestMapping("/map")
|
||||||
|
public void map(@RequestParam Map<String, String> params, Writer writer) throws IOException {
|
||||||
|
for (Iterator<Map.Entry<String, String>> it = params.entrySet().iterator(); it.hasNext();) {
|
||||||
|
Map.Entry<String, String> entry = it.next();
|
||||||
|
writer.write(entry.getKey() + "=" + entry.getValue());
|
||||||
|
if (it.hasNext()) {
|
||||||
|
writer.write(',');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/multiValueMap")
|
||||||
|
public void multiValueMap(@RequestParam MultiValueMap<String, String> params, Writer writer) throws IOException {
|
||||||
|
for (Iterator<Map.Entry<String, List<String>>> it1 = params.entrySet().iterator(); it1.hasNext();) {
|
||||||
|
Map.Entry<String, List<String>> entry = it1.next();
|
||||||
|
writer.write(entry.getKey() + "=[");
|
||||||
|
for (Iterator<String> it2 = entry.getValue().iterator(); it2.hasNext();) {
|
||||||
|
String value = it2.next();
|
||||||
|
writer.write(value);
|
||||||
|
if (it2.hasNext()) {
|
||||||
|
writer.write(',');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writer.write(']');
|
||||||
|
if (it1.hasNext()) {
|
||||||
|
writer.write(',');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
@ -46,6 +47,8 @@ import org.springframework.ui.Model;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.util.ReflectionUtils;
|
import org.springframework.util.ReflectionUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.util.MultiValueMap;
|
||||||
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
import org.springframework.validation.BindingResult;
|
import org.springframework.validation.BindingResult;
|
||||||
import org.springframework.validation.Errors;
|
import org.springframework.validation.Errors;
|
||||||
import org.springframework.web.HttpMediaTypeNotSupportedException;
|
import org.springframework.web.HttpMediaTypeNotSupportedException;
|
||||||
|
|
@ -396,11 +399,15 @@ public class HandlerMethodInvoker {
|
||||||
return initBinderArgs;
|
return initBinderArgs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
private Object resolveRequestParam(String paramName, boolean required, String defaultValue,
|
private Object resolveRequestParam(String paramName, boolean required, String defaultValue,
|
||||||
MethodParameter methodParam, NativeWebRequest webRequest, Object handlerForInitBinderCall)
|
MethodParameter methodParam, NativeWebRequest webRequest, Object handlerForInitBinderCall)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
|
||||||
Class<?> paramType = methodParam.getParameterType();
|
Class<?> paramType = methodParam.getParameterType();
|
||||||
|
if (Map.class.isAssignableFrom(paramType)) {
|
||||||
|
return resolveRequestParamMap((Class<? extends Map>) paramType, webRequest);
|
||||||
|
}
|
||||||
if (paramName.length() == 0) {
|
if (paramName.length() == 0) {
|
||||||
paramName = getRequiredParameterName(methodParam);
|
paramName = getRequiredParameterName(methodParam);
|
||||||
}
|
}
|
||||||
|
|
@ -428,6 +435,28 @@ public class HandlerMethodInvoker {
|
||||||
return binder.convertIfNecessary(paramValue, paramType, methodParam);
|
return binder.convertIfNecessary(paramValue, paramType, methodParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Map resolveRequestParamMap(Class<? extends Map> mapType, NativeWebRequest webRequest) {
|
||||||
|
Map<String, String[]> parameterMap = webRequest.getParameterMap();
|
||||||
|
if (MultiValueMap.class.isAssignableFrom(mapType)) {
|
||||||
|
MultiValueMap<String, String> result = new LinkedMultiValueMap<String, String>(parameterMap.size());
|
||||||
|
for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
|
||||||
|
for (String value : entry.getValue()) {
|
||||||
|
result.add(entry.getKey(), value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Map<String, String> result = new LinkedHashMap<String, String>(parameterMap.size());
|
||||||
|
for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
|
||||||
|
if (entry.getValue().length > 0) {
|
||||||
|
result.put(entry.getKey(), entry.getValue()[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Object resolveRequestHeader(String headerName, boolean required, String defaultValue,
|
private Object resolveRequestHeader(String headerName, boolean required, String defaultValue,
|
||||||
MethodParameter methodParam, NativeWebRequest webRequest, Object handlerForInitBinderCall)
|
MethodParameter methodParam, NativeWebRequest webRequest, Object handlerForInitBinderCall)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue