随笔
Spring MVC的参数解析器
概要
- 以form表单的形式传入数据,不论你传的是deviceId[0]=1,还是deviceId=1,2,3,又或者是直接传入dto.id=123456这样的,都能在后台准确的接收到,这是为什么?
环境
springBoot2.5.5+web环境
实体类自定义
代码开始
-
首先我们看到的是
它是能够成功接收到的
-
现在开始看看源码是怎么处理这些的,这么智能
从RequestMappingHandlerAdapter的invokeHandlerMethod方法开始,这个就是将request中的数据解析出来的源头
- 继续进去看看怎么解析的
-
看看映射具体操作
这个就比较熟悉了,看到了HandlerMethodArgumentResolve接口的方法,一个判断是否支持,一个执行参数解析
我们直接看执行参数解析吧
可以看到attribute的类型是我们controller的方法参数,然后就到了bind里面了,所以关注bind的属性值变化,发现过了蓝色那块的代码之后,它有值了,所以,进去看看
前面都没有改变bind的属性值,那么只能是最后一行了,进去看看
看this里面知道,还是在最后一行,继续
继续
继续
for循环key值,然后处理
这个估计就是标记的作用,可以看看后面运行出来之后就到了这
这个方法的主要功能是把deviceId[0]这样的参数封装成一个对象PropertyTokenHolder
进入setproperty
继续
我传了两个deviceId[]的格式,现在看看deviceId[1],直接跳到setProperty
-
上面的就是deviceId[0],deviceId[1]这些参数解析的操作
-
下面看看deviceId=1,2,3,4这样的是怎么赋值的
在上面的基础上,直接到setProperty
spring 会拿到它的数据类型,然后将拿到的数据进行转换,然后赋值
-
下面我们看看dto.xxx的效果
由于是有.,所以最终返回的就不是之前的-1了,而是返回数据.所在的位置
然后就是把数据封装,dto和xxx封装
值得注意的是,多了一个rootObject对象。后面的就变成对属性的子对象进行赋值了,所以步骤和正常的是一致的。
以上为我的个人见解,如有错误,烦请指出,不胜感激