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函数,如下图

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;
        }
    }
}

上面代码的执行如下图:

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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,368评论 19 139
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,444评论 11 349
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,929评论 18 399
  • 话说现在相应的压力增大,那就努力工作,努力赚钱,想问怎么才能算努力工作哪?思维中的行动力在哪?要敢于打破舒服一...
    无花果果果阅读 1,768评论 0 0
  • 01 以前我花很多时间,担心自己是不是和别人不同。事实上,无论我们是富是穷,或是介于中间,这个世界都不是我们最后的...
    愿众生平安幸福阅读 1,690评论 2 4