0x00 问题初现
“抱着沙发 睡眼昏花 凌乱头发…” 中午正沉浸在音乐中呢,嘀·嘀·嘀 ,原来是小老弟发来微信问为啥他的接口一直报400,很明显的@RequestBody和@RequestParam用错了,让小老弟改了下,就又带上了耳机。想着还是记录下来,以后也不用再给小老弟解释类似的问题了。
0x01 开始出发
直接从我们熟悉的DispatcherServlet.doDispatch 出发一直到 HandlerMethodArgumentResolverComposite.resolveArgument 方法中间的调用链比较清晰,这里不再着重关注。
直接从第一个关键方法开始说起:
从方法名称就能看出来方法是用来解析参数的。方法注释 迭代已经注册的HandlerMethodArgumentResolver 找到适配的并调用,如果没有合适的就抛异常。说明这个方法主要就是做了两件事:1.找到合适的 HandlerMethodArgumentResolver;2.调用;
如上图看到的步骤1就是遍历的过程,步骤2就是调用的过程。
进入 getArgumentResolver
整个过程比较简单,就是遍历和判断,那么问题来了,argumentResolvers 是在哪里注册进来这么多参数解析器的?判断是否支持的逻辑是什么?
我们先看第二个问题,点开几个实现类一看基本都没有很复杂的逻辑,很多都是只判断是否有对应的注解
这里就有想法了,我自己定义一个注解,实现一个参数解析器是不是就可以实现自定义参数注解了,先不急。
回过头来看参数解析器的注册,打上断点,查看调用栈
这里就是直接new出来的,不再赘述
0x02 参数解析器的调用
参数解析器太多了,这里就只简单介绍 @RequestBody 和 @RequestParam的参数解析过程了。
就是根据注解的不同找到对应的HandlerMethodArgumentResolver实现类,调用resolveArgument方法,仔细想了下,这里后续逻辑比较简单,不再啰嗦了。
@RequestParam就是直接获取了
Map<String, String[]> parameterMap = webRequest.getParameterMap();
@RequestBody的 参数处理还有个以前没注意过的有趣的工具-ObjectMapper,
一个专门用来读写JSON的工具类,好东西~~~
0x03 自定义参数注解
自定义注解分为三个步骤:
1.注解类。
2.参数解析器实现类
3.将参数解析器加到argumentResolvers中
自定义注解还是开个单章写写吧,内容也不少。。。