美文网首页java学习之路
spring boot2 (五)web中获取请求参数及原理

spring boot2 (五)web中获取请求参数及原理

作者: 唯有努力不欺人丶 | 来源:发表于2021-01-14 22:40 被阅读0次

    我反正开发三年多,最常用的还是正常参数的形式传递获取。不过这个路径传参据说是restful风格的常用方式(我是个土鳖,restful风格也没实际用过)。
    所以针对多种传参方式,这里也简单的记录一下:

    路径传参

    这个不仅仅是restful风格可以用,其实本质就是从路径的某段中获取参数,只要使用一个注释:

    @PathVariable
    

    下面是简单的使用 demo:


    路径传参方法

    然后我们去接口访问这个方法:


    访问结果
    事实证明,路径上带参数,我们用@PathVariable注解获取到了。
    至于最后一个获取map的用法,其实在注解中是有说到的。
    获取所有路径传参,用map<String,String>类型

    获取请求头信息

    这个其实也挺有用的,很多时候token都是放在请求头的,当然了还有别的东西也都ok。而获取请求头的方法除了我们在方法中用request获取,也可以直接获取。

    @RequestHeader
    

    其实这个方法和上面那个差不多。可以指定获取,也可以用map获取全部的。如下demo:


    获取请求头全部信息

    虽然看上去不怎么好看,但是起码证明确实获取到请求头了。这个就过了。

    获取参数

    这个就是正常参数了,依然一个注解:

    @RequestParam
    

    使用方法和上面一样,指定参数名称,或者获取全部参数(全部参数的话必须是String,String 的)。


    获取全部参数

    获取cookie

    依旧一个注解开始:

    @CookieValue
    

    需要注意的是这个cookie是没有map的,看官网文档的说法,要用cookie接收:


    cookie类型

    因为我没前端页面都,所以这个访问要用postman来添加cookie再测试:


    image.png

    cookie的接收测试完毕。

    常用的就这几个,接下来重点说参数获取的原理(这里用debug一步一步调试):

    首先我们的测试代码是这样的:


    请求

    其实这个是继续上文说找到那个请求处理器以后的发展了,上文说通过DispatcherServlet类的getHandler方法,找到url所对应的方法全名称。这里仍然debug一步一步走:


    走到这个方法
    这里有一个小窍门:一般带注释的方法都是值得一看的。我是习惯性百度翻译一下看看的。然后继续往下走到下一个方法:
    走到这个方法,进入方法中

    ps:这里很多走到接口,然后进入实现方法的。反正见到方法就进入就行了


    走到这个方法

    其实这个类应该是个很重要的类,毕竟大量invoke方法。然后我们一步一步往下走:


    下一步就走到这个方法

    因为我这个方法就是普通方法,所以走到这个方法中。其实从它的名字中午文翻译:反射 处理器 方法。大概可以猜测是方法反射的处理器。
    点进去以后继续一步一步走:


    进入方法中
    这个方法中代码很多,但是首先我觉得set本身不会存在赋值行为,所以说前面所有的set我都一路往下。最终走到一个看名字就高大上是方法:
    看名字就觉得是有用的方法

    然后点进这个方法:


    点进这个方法中第一行代码又进入一个invoke的方法,所以再点进去
    往里走接下来我手欠走过了,如下截图:
    参数已经找到了
    到我当前断点的位置,参数都已经赋值了,因为我断点已经过了, 所以直接看看走过的代码:
    给参数赋值的代码

    其实这个代码逻辑还算是简单,首先创建了一个参数长度的Object数组用来存参数。然后还是一个个 去找参数的值(中间用到了参数解析器)。找到以后continue,去找下一个参数。这里有一点要注意:找不到的话,会报错的!就是我常见的那个错:


    找不到参数报错

    哎,因为断点跟丢了现在好难受,我从新走一遍吧。
    继续上面说的,给参数赋值的方法如下:


    给参数赋值方法
    点进去查看:
    实现赋值方法

    继续点进去:


    判断当前参数类型是否支持
    这个就用到了我们上面说的spring boot自带的26个参数类型解析器。可以点进去瞅瞅:
    是一个方法的是否为空的判断
    进方法中看:
    方法就是一个简单的for循环比对
    这里重点的是我圈起来的:argumentResolvers这个参数就是spring boot默认的所有解析器的集合。
    如果这里返回null说明当前参数类型不支持,所以为空,最终出去就直接报错了。
    spring boot不支持的参数类型就在这里报错
    当有这个类型以后去赋值,继续往下走到了赋值的方法:
    赋值方法

    其实这里又查找了下,确定是有这个类型的。继续往下走:


    根据类型不同去找对应的解析器的方法
    其实这里很有意思,大家可以注意这个解析器和注解的名称密切相关啊。比如我demo中用的两个注解:一个@PathVariable一个@RequestParam。
    至于里面的实现我是真的懒得一个个看了,眼晕。
    其实这里可能是因为框架完善的原因,很多设计是为了扩展性或者维护性啥。所以debug的时候要不断父子类方法跳,我简单说下我对这块的理解:
    1. 获取参数个数。
    2. 判断参数是不是spring boot能解析的类型(这里涉及到spring boot默认的解析器)。
    3. 获取参数上的注释和指定名称(如果指定名称的参数不存在则报错)。
    4. 将参数名称和实际值对应起来。
    5. web数据绑定器,将请求参数的值绑定到指定的JavaBean里面。WebDataBinder 利用它里面的 Converters 将请求数据转成指定的数据类型。再次封装到JavaBean中。
    6. 所有的参数都这么走一遍。


      参数名报错

      反正大概就是这么个过程吧,这一块我debug跟丢好多次,目前而言背是把这个断点的走向背出来了。大概也理解了。但是说多熟,能分析的特别明白还是不敢说的。
      而且就这么一个赋值方法,来来回回蹦跶了十几个方法,也是够了。就这样吧。

    本篇笔记就到这里,如果稍微帮到你了记得点个喜欢点个关注,也祝大家工作顺顺利利!另外如果文中哪里表述不严瑾或者有问题欢迎指出!

    相关文章

      网友评论

        本文标题:spring boot2 (五)web中获取请求参数及原理

        本文链接:https://www.haomeiwen.com/subject/hwxmaktx.html