springMVC源码分析--RequestParamMethodArgumentResolver参数解析器(三)

之前两篇博客springMVC源码分析--HandlerMethodArgumentResolver参数解析器(一) springMVC源码解析--HandlerMethodArgumentResolverComposite参数解析器集合(二)我们对参数解析器有一些了解了,接下来这篇博客我们选取一个HandlerMethodArgumentResolver的具体实现类RequestParamMethodArgumentResolver来简单介绍一下具体的参数解析过程。RequestParamMethodArgumentResolver简单来说就是对一个请求参数值的解析,将请求中的参数值解析成为Controller函数中参数需要的具体数据类型。

Controller中函数需要的参数

    @RequestMapping("/getdata")
    @ResponseBody
    public Object getData(String name,Integer age){
    	return name+""+age;
    }
我们发起的请求链接

http://localhost/product/getdata.action?name=admin&age=10

接下来我们跟踪一下代码看看springMVC是如何将请求中的参数name=admin和age=10解析成为函数中需要的具体数据类型String和Integer。

首先参数解析会到AbstractNamedValueMethodArgumentResolver类的resolveArgument函数,如下图



首先会获取request中的参数name及值,接下来是在RequestParamMethodArgumentResolver类的resolveName函数中获取这个参数的值

protected Object resolveName(String name, MethodParameter parameter, NativeWebRequest webRequest) throws Exception {
	......	
	if (arg == null) {
		String[] paramValues = webRequest.getParameterValues(name);
		if (paramValues != null) {
			arg = (paramValues.length == 1 ? paramValues[0] : paramValues);
		}
	}
	
	return arg;
}
上面代码的执行如下图:


这样就获取了name=admini这个值。

参数转换的过程主要是在AbstractNamedValueMethodArgumentResolver类的resolveArgument函数中,主要是获取参数值和将参数转换为Controller中函数需要的参数类型。

@Override
	public final Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
			NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {

		Class<?> paramType = parameter.getParameterType();
		NamedValueInfo namedValueInfo = getNamedValueInfo(parameter);
		//从request中获取参数值
		Object arg = resolveName(namedValueInfo.name, parameter, webRequest);
		if (arg == null) {
			if (namedValueInfo.defaultValue != null) {
				arg = resolveDefaultValue(namedValueInfo.defaultValue);
			}
			else if (namedValueInfo.required && !parameter.getParameterType().getName().equals("java.util.Optional")) {
				handleMissingValue(namedValueInfo.name, parameter);
			}
			arg = handleNullValue(namedValueInfo.name, arg, paramType);
		}
		else if ("".equals(arg) && namedValueInfo.defaultValue != null) {
			arg = resolveDefaultValue(namedValueInfo.defaultValue);
		}
		//将获取的参数值转换为Controller中函数需要的数据类型
		if (binderFactory != null) {
			WebDataBinder binder = binderFactory.createBinder(webRequest, null, namedValueInfo.name);
			try {
				arg = binder.convertIfNecessary(arg, paramType, parameter);
			}
			catch (ConversionNotSupportedException ex) {
				throw new MethodArgumentConversionNotSupportedException(arg, ex.getRequiredType(),
						namedValueInfo.name, parameter, ex.getCause());
			}
			catch (TypeMismatchException ex) {
				throw new MethodArgumentTypeMismatchException(arg, ex.getRequiredType(),
						namedValueInfo.name, parameter, ex.getCause());

			}
		}

		handleResolvedValue(arg, namedValueInfo.name, parameter, mavContainer, webRequest);

		return arg;
	}



  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值