diff --git a/spring-web/src/main/java/org/springframework/web/bind/annotation/RequestMapping.java b/spring-web/src/main/java/org/springframework/web/bind/annotation/RequestMapping.java index fe93c5b159a..4ea7e7e6ab2 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/annotation/RequestMapping.java +++ b/spring-web/src/main/java/org/springframework/web/bind/annotation/RequestMapping.java @@ -79,6 +79,9 @@ import java.util.concurrent.Callable; * will match against the regular expression {@code [^\.]*} (i.e. any character * other than period), but this can be changed by specifying another regular * expression, like so: /hotels/{hotel:\d+}. + * Additionally, {@code @PathVariable} can be used on a + * {@link java.util.Map Map<String, String>} to gain access to all + * URI template variables. *
If the method parameter type is {@link Map}, the request parameter name is used to - * resolve the request parameter String value. The value is then converted to a {@link Map} - * via type conversion assuming a suitable {@link Converter} or {@link PropertyEditor} has - * been registered. If a request parameter name is not specified with a {@link Map} method - * parameter type, the {@link RequestParamMapMethodArgumentResolver} is used instead - * providing access to all request parameters in the form of a map. - * - *
A {@link WebDataBinder} is invoked to apply type conversion to resolved request + * + *
If the method parameter type is {@link Map}, the name specified in the + * annotation is used to resolve the request parameter String value. The value is + * then converted to a {@link Map} via type conversion assuming a suitable + * {@link Converter} or {@link PropertyEditor} has been registered. + * Or if a request parameter name is not specified the + * {@link RequestParamMapMethodArgumentResolver} is used instead to provide + * access to all request parameters in the form of a map. + * + *
A {@link WebDataBinder} is invoked to apply type conversion to resolved request * header values that don't yet match the method parameter type. - * + * * @author Arjen Poutsma * @author Rossen Stoyanchev * @since 3.1 @@ -72,15 +73,15 @@ public class RequestParamMethodArgumentResolver extends AbstractNamedValueMethod private final boolean useDefaultResolution; /** - * @param beanFactory a bean factory used for resolving ${...} placeholder - * and #{...} SpEL expressions in default values, or {@code null} if default + * @param beanFactory a bean factory used for resolving ${...} placeholder + * and #{...} SpEL expressions in default values, or {@code null} if default * values are not expected to contain expressions - * @param useDefaultResolution in default resolution mode a method argument - * that is a simple type, as defined in {@link BeanUtils#isSimpleProperty}, - * is treated as a request parameter even if it itsn't annotated, the + * @param useDefaultResolution in default resolution mode a method argument + * that is a simple type, as defined in {@link BeanUtils#isSimpleProperty}, + * is treated as a request parameter even if it itsn't annotated, the * request parameter name is derived from the method parameter name. */ - public RequestParamMethodArgumentResolver(ConfigurableBeanFactory beanFactory, + public RequestParamMethodArgumentResolver(ConfigurableBeanFactory beanFactory, boolean useDefaultResolution) { super(beanFactory); this.useDefaultResolution = useDefaultResolution; @@ -89,15 +90,15 @@ public class RequestParamMethodArgumentResolver extends AbstractNamedValueMethod /** * Supports the following: *
An @{@link PathVariable} is a named value that gets resolved from a URI template variable. It is always - * required and does not have a default value to fall back on. See the base class - * {@link org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver} for more information on how named values are processed. - * - *
A {@link WebDataBinder} is invoked to apply type conversion to resolved path variable values that + *
An @{@link PathVariable} is a named value that gets resolved from a URI + * template variable. It is always required and does not have a default value + * to fall back on. See the base class + * {@link org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver} + * for more information on how named values are processed. + * + *
If the method parameter type is {@link Map}, the name specified in the + * annotation is used to resolve the URI variable String value. The value is + * then converted to a {@link Map} via type conversion assuming a suitable + * {@link Converter} or {@link PropertyEditor} has been registered. + * Or if the annotation does not specify name the + * {@link RequestParamMapMethodArgumentResolver} is used instead to provide + * access to all URI variables in a map. + * + *
A {@link WebDataBinder} is invoked to apply type conversion to resolved path variable values that
* don't yet match the method parameter type.
- *
+ *
* @author Rossen Stoyanchev
* @author Arjen Poutsma
* @since 3.1
@@ -52,7 +66,14 @@ public class PathVariableMethodArgumentResolver extends AbstractNamedValueMethod
}
public boolean supportsParameter(MethodParameter parameter) {
- return parameter.hasParameterAnnotation(PathVariable.class);
+ if (!parameter.hasParameterAnnotation(PathVariable.class)) {
+ return false;
+ }
+ if (Map.class.isAssignableFrom(parameter.getParameterType())) {
+ String paramName = parameter.getParameterAnnotation(PathVariable.class).value();
+ return StringUtils.hasText(paramName);
+ }
+ return true;
}
@Override
@@ -64,7 +85,7 @@ public class PathVariableMethodArgumentResolver extends AbstractNamedValueMethod
@Override
@SuppressWarnings("unchecked")
protected Object resolveName(String name, MethodParameter parameter, NativeWebRequest request) throws Exception {
- Map