5

What I want to do is passing a map to the method in Controller using @RequestParam, but it seems not working. While this is working in Struts 2 as value binding.

Below is what I am trying: In JSP using JQuery:

var order = {};
order['seq'] = "ASC";
var criteria = {};
criteria['label'] = "Directory";

$.post(context + 'menu/list',
    {"orders" : order,
     "criterias" : criteria}

The parameters I am trying to post is an 'map' object order and criteria for listing menu. In Java:

    @RequestMapping("/{collection}/list")
public @ResponseBody Map<String, ? extends Object> list(@PathVariable String collection,
        @RequestParam("criterias") Map<String, String> criteria,
        @RequestParam("orders") Map<String, String> order) {

However, when I print out the map criteria & order in Java, it takes all value as below:

Criteria: {criterias[label]=Directory, orders[seq]=ASC}
Order: {criterias[label]=Directory, orders[seq]=ASC}

Can @RequestParam in Spring be used to init a Map parameter?

1 Answer 1

4

OK. Seems I find the reason.

In HandlerMethodInvoker.java

@SuppressWarnings("unchecked")
private Object resolveRequestParam(String paramName, boolean required, String defaultValue,
        MethodParameter methodParam, NativeWebRequest webRequest, Object handlerForInitBinderCall)
        throws Exception {

    Class<?> paramType = methodParam.getParameterType();
    if (Map.class.isAssignableFrom(paramType)) {
        return resolveRequestParamMap((Class<? extends Map>) paramType, webRequest);
    }}


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;
    }
}

When it checks that if my @RequestParam annotated parameter is Map class type, it puts all request parameters into this parameter as MultiValueMap or Linked HashMap

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.