RequestParamMethodArgumentResolver参数解析过程
RequestParamMethodArgumentResolver
是最重要的几个参数解析器(HandlerMethodArgumentResolver
)之一。在实际开发中,大部分的Get请求参数都是通过它来解析的。
哪些参数会通过RequestParamMethodArgumentResolver
解析?
我们先来弄清楚一个问题,如果参数上没有加@RequestParam
注解,那这个参数的解析会交给RequestParamMethodArgumentResolver
来进行解析吗?
默认情况下RequestParamMethodArgumentResolver
只处理带有@RequestParam
注解以及MultipartFile
、Part
类型和一些简单类型参数。也就是说MultipartFile
、Part
类型和一些简单类型参数哪怕没有@RequestParam
注解,也会交给RequestParamMethodArgumentResolver
来解析。
@Override
public boolean supportsParameter(MethodParameter parameter) {
if (parameter.hasParameterAnnotation(RequestParam.class)) {
if (Map.class.isAssignableFrom(parameter.nestedIfOptional().getNestedParameterType())) {
RequestParam requestParam = parameter.getParameterAnnotation(RequestParam.class);
return (requestParam != null && StringUtils.hasText(requestParam.name()));
}
else {
return true;
}
}
else {
if (parameter.hasParameterAnnotation(RequestPart.class)) {
return false;
}
parameter = parameter.nestedIfOptional();
if (MultipartResolutionDelegate.isMultipartArgument(parameter)) {
return true;
}
else if (this.useDefaultResolution) {
// 判断是否是简单类型
return BeanUtils.isSimpleProperty(parameter.getNestedParameterType());
}
else {
return false;
}
}
}
可以从org.springframework.beans.BeanUtils#isSimpleProperty
的源码中看出简单类型包括哪些。
public static boolean isSimpleProperty(Class<?> type) {
Assert.notNull(type, "'type' must not be null");
return isSimpleValueType(type) || (type.isArray() && isSimpleValueType(type.componentType()));
}
public static boolean isSimpleValueType(Class<?> type) {
return ClassUtils.isSimpleValueType(type);
}
public static boolean isSimpleValueType(Class<?> type) {
return (!isVoidType(type) &&
(isPrimitiveOrWrapper(type) ||
Enum.class.isAssignableFrom(type) ||
CharSequence.class.isAssignableFrom(type) ||
Number.class.isAssignableFrom(type) ||
Date.class.isAssignableFrom(type) ||
Temporal.class.isAssignableFrom(type) ||
ZoneId.class.isAssignableFrom(type) ||
TimeZone.class.isAssignableFrom(type) ||
File.class.isAssignableFrom(type) ||
Path.class.isAssignableFrom(type) ||
Charset.class.isAssignableFrom(type) ||
Currency.class.isAssignableFrom(type) ||
InetAddress.class.isAssignableFrom(type) ||
URI.class == type ||
URL.class == type ||
UUID.class == type ||
Locale.class == type ||
Pattern.class == type ||
Class.class == type));
}