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

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

@RequestMapping("/getdata")  
@ResponseBody  
public Object getData(String name,Integer age){  
    return name+""+age;  
}  

我们发起的请求链接
http://localhost/product/getdata.action?name=admini&age=10
接下来我们跟踪一下代码看看springMVC是如何将请求中的参数name=admini和age=10解析成为函数中需要的具体数据类型String和Integer。
首先参数解析会到AbstractNamedValueMethodArgumentResolver类的resolveArgument函数,如下图

springMVC源码分析--RequestParamMethodArgumentResolver参数解析器(三)_第1张图片
resolveArgument函数.png

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

public class RequestParamMethodArgumentResolver extends AbstractNamedValueMethodArgumentResolver implements UriComponentsContributor {
    ......
    protected Object resolveName(String name, MethodParameter parameter, NativeWebRequest request) throws Exception {
        HttpServletRequest servletRequest = (HttpServletRequest)request.getNativeRequest(HttpServletRequest.class);
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest)WebUtils.getNativeRequest(servletRequest, MultipartHttpServletRequest.class);
        Object mpArg = MultipartResolutionDelegate.resolveMultipartArgument(name, parameter, servletRequest);
        if(mpArg != MultipartResolutionDelegate.UNRESOLVABLE) {
            return mpArg;
        } else {
            Object arg = null;
            if(multipartRequest != null) {
                List paramValues = multipartRequest.getFiles(name);
                if(!paramValues.isEmpty()) {
                    arg = paramValues.size() == 1?paramValues.get(0):paramValues;
                }
            }


            if(arg == null) {
                String[] paramValues1 = request.getParameterValues(name);
                if(paramValues1 != null) {
                    arg = paramValues1.length == 1?paramValues1[0]:paramValues1;
                }
            }

            return arg;
        }
    }
}

上面代码的执行如下图:

springMVC源码分析--RequestParamMethodArgumentResolver参数解析器(三)_第2张图片
resolveName方法.png

这样就获取了name=admini这个值。
参数转换的过程主要是在AbstractNamedValueMethodArgumentResolver类的resolveArgument函数中,主要是获取参数值和将参数转换为Controller中函数需要的参数类型。

public final Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, 
NativeWebRequest webRequest,WebDataBinderFactory binderFactory) throws Exception {
        AbstractNamedValueMethodArgumentResolver.NamedValueInfo namedValueInfo = this.getNamedValueInfo(parameter);
        MethodParameter nestedParameter = parameter.nestedIfOptional();
        Object resolvedName = this.resolveStringValue(namedValueInfo.name);
        if(resolvedName == null) {
            throw new IllegalArgumentException("Specified name must not resolve to null: [" + namedValueInfo.name + "]");
        } else {
            //从request中获取参数值 
            Object arg = this.resolveName(resolvedName.toString(), nestedParameter, webRequest);
            if(arg == null) {
                if(namedValueInfo.defaultValue != null) {
                    arg = this.resolveStringValue(namedValueInfo.defaultValue);
                } else if(namedValueInfo.required && !nestedParameter.isOptional()) {
                    this.handleMissingValue(namedValueInfo.name, nestedParameter, webRequest);
                }

                arg = this.handleNullValue(namedValueInfo.name, arg, nestedParameter.getNestedParameterType());
            } else if("".equals(arg) && namedValueInfo.defaultValue != null) {
                arg = this.resolveStringValue(namedValueInfo.defaultValue);
            }

             //将获取的参数值转换为Controller中函数需要的数据类型  
            if(binderFactory != null) {
                WebDataBinder binder = binderFactory.createBinder(webRequest, (Object)null, namedValueInfo.name);

                try {
                    arg = binder.convertIfNecessary(arg, parameter.getParameterType(), parameter);
                } catch (ConversionNotSupportedException var11) {
                    throw new MethodArgumentConversionNotSupportedException(arg, var11.getRequiredType(), namedValueInfo.name, parameter, var11.getCause());
                } catch (TypeMismatchException var12) {
                    throw new MethodArgumentTypeMismatchException(arg, var12.getRequiredType(), namedValueInfo.name, parameter, var12.getCause());
                }
            }

            this.handleResolvedValue(arg, namedValueInfo.name, parameter, mavContainer, webRequest);
            return arg;
        }
    }
转载于:http://blog.csdn.net/qq924862077/article/details/54292082

你可能感兴趣的:(springMVC源码分析--RequestParamMethodArgumentResolver参数解析器(三))