我反正开发三年多,最常用的还是正常参数的形式传递获取。不过这个路径传参据说是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的时候要不断父子类方法跳,我简单说下我对这块的理解:
- 获取参数个数。
- 判断参数是不是spring boot能解析的类型(这里涉及到spring boot默认的解析器)。
- 获取参数上的注释和指定名称(如果指定名称的参数不存在则报错)。
- 将参数名称和实际值对应起来。
- web数据绑定器,将请求参数的值绑定到指定的JavaBean里面。WebDataBinder 利用它里面的 Converters 将请求数据转成指定的数据类型。再次封装到JavaBean中。
-
所有的参数都这么走一遍。
参数名报错
反正大概就是这么个过程吧,这一块我debug跟丢好多次,目前而言背是把这个断点的走向背出来了。大概也理解了。但是说多熟,能分析的特别明白还是不敢说的。
而且就这么一个赋值方法,来来回回蹦跶了十几个方法,也是够了。就这样吧。
本篇笔记就到这里,如果稍微帮到你了记得点个喜欢点个关注,也祝大家工作顺顺利利!另外如果文中哪里表述不严瑾或者有问题欢迎指出!
网友评论