001/* 002 * Copyright 2002-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.web.method.annotation; 018 019import java.util.LinkedHashMap; 020import java.util.Map; 021 022import org.springframework.core.MethodParameter; 023import org.springframework.util.LinkedMultiValueMap; 024import org.springframework.util.MultiValueMap; 025import org.springframework.util.StringUtils; 026import org.springframework.web.bind.annotation.RequestParam; 027import org.springframework.web.bind.support.WebDataBinderFactory; 028import org.springframework.web.context.request.NativeWebRequest; 029import org.springframework.web.method.support.HandlerMethodArgumentResolver; 030import org.springframework.web.method.support.ModelAndViewContainer; 031 032/** 033 * Resolves {@link Map} method arguments annotated with an @{@link RequestParam} 034 * where the annotation does not specify a request parameter name. 035 * See {@link RequestParamMethodArgumentResolver} for resolving {@link Map} 036 * method arguments with a request parameter name. 037 * 038 * <p>The created {@link Map} contains all request parameter name/value pairs. 039 * If the method parameter type is {@link MultiValueMap} instead, the created 040 * map contains all request parameters and all their values for cases where 041 * request parameters have multiple values. 042 * 043 * @author Arjen Poutsma 044 * @author Rossen Stoyanchev 045 * @since 3.1 046 * @see RequestParamMethodArgumentResolver 047 */ 048public class RequestParamMapMethodArgumentResolver implements HandlerMethodArgumentResolver { 049 050 @Override 051 public boolean supportsParameter(MethodParameter parameter) { 052 RequestParam requestParam = parameter.getParameterAnnotation(RequestParam.class); 053 return (requestParam != null && Map.class.isAssignableFrom(parameter.getParameterType()) && 054 !StringUtils.hasText(requestParam.name())); 055 } 056 057 @Override 058 public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, 059 NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { 060 061 Map<String, String[]> parameterMap = webRequest.getParameterMap(); 062 if (MultiValueMap.class.isAssignableFrom(parameter.getParameterType())) { 063 MultiValueMap<String, String> result = new LinkedMultiValueMap<String, String>(parameterMap.size()); 064 for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) { 065 for (String value : entry.getValue()) { 066 result.add(entry.getKey(), value); 067 } 068 } 069 return result; 070 } 071 else { 072 Map<String, String> result = new LinkedHashMap<String, String>(parameterMap.size()); 073 for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) { 074 if (entry.getValue().length > 0) { 075 result.put(entry.getKey(), entry.getValue()[0]); 076 } 077 } 078 return result; 079 } 080 } 081 082}