六、请求处理—获取请求参数系列注解是怎样工作的?

六、请求处理—获取请求参数系列注解是怎样工作的?

  在Spring MVC中,有许多常用的注解,我们给方法的参数前边标注这些注解,Spring MVC就会帮我们按照要求,在调用目标方法的时候,帮这些参数确定好值,我们就可以在下边使用了,总结如下:

@PathVariable -->(获取路径变量)

@RequestHeader -->(获取请求头)

@RequestParam -->(获取请求参数)

@CookieValue -->(获取cookie值)

@RequestBody -->(获取请求体[POST])

@RequestAttribute -->(获取request域属性)

@MatrixVariable -->(矩阵变量)

  我们已经很熟练的使用这些注解了,但是,这其中的原理是什么,你知道吗?

  同样,来到处理所有请求的入口 DispatcherServlet 的 doDispatch() 方法

在这里插入图片描述
  这里是上一片看过的请求映射部分,找到了这个请求对应的handler,这里就不在赘述了,继续往下看

在这里插入图片描述

在这里插入图片描述

  找到适配器以后,看他要干什么

  再往下走,来到 handle 这个关键方法,这个方法传入了request、response和我们的目标方法,它来帮我们执行目标方法,如下
在这里插入图片描述
  继续点击step into,就会来到 RequestMappingHandlerAdapter 类的 handleInternal() 方法,然后来到这个方法的 invokeHandlerMethod() 调用,来执行目标方法

在这里插入图片描述
  进入这个方法
在这里插入图片描述
  参数解析器是一个接口,里边有两个方法,作用如下

在这里插入图片描述

  参数解析器下边还有一个返回值处理器,默认15种
在这里插入图片描述
  Spring mvc提前帮我们把这些解析器、处理器都放到了 ServletInvocableHandlerMethod 里边,继续往下走,跳过中间一些不重要的,直接来到真正执行目标方法的方法

在这里插入图片描述
  进入这个方法,如下

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
  我们来看这一行代码里边做了什么,如何执行目标方法的

在这里插入图片描述

protected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {
        //获取方法上所有参数的详细信息
        MethodParameter[] parameters = this.getMethodParameters();
        //判空,没有参数列表就直接返回
        if (ObjectUtils.isEmpty(parameters)) {
            return EMPTY_ARGS;
        } else {
        	//这里new了一个参数个数长度的Object数组
            Object[] args = new Object[parameters.length];
			//挨个遍历
            for(int i = 0; i < parameters.length; ++i) {
            	//拿到第i个参数
                MethodParameter parameter = parameters[i];
                //初始化
                parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);
                args[i] = findProvidedArgument(parameter, providedArgs);
                if (args[i] == null) {
                	//判断当前解析器是不是支持这种参数类型
                	//就是遍历前边的那26个参数解析器,看谁支持当前参数
                	//找到之后放入缓存
                    if (!this.resolvers.supportsParameter(parameter)) {
                        throw new IllegalStateException(formatArgumentError(parameter, "No suitable resolver"));
                    }

                    try {
                    	//从缓存拿对应的解析器,进行解析
                        args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);
                    } catch (Exception var10) {
                        if (this.logger.isDebugEnabled()) {
                            String exMsg = var10.getMessage();
                            if (exMsg != null && !exMsg.contains(parameter.getExecutable().toGenericString())) {
                                this.logger.debug(formatArgumentError(parameter, exMsg));
                            }
                        }

                        throw var10;
                    }
                }
            }

            return args;
        }
    }

在这里插入图片描述
  接下来接没有必要再跟进去了,里边就到我们的反射工具类了。

  经过一步一步的debug,我们终于搞明白那些参数注解是怎样获取值的,其实原理也很简单,就是找到自己匹配的参数解析器,解析出请求参数而且,多debug几遍也就轻车熟路了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Anton丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值