当前位置:网站首页>七、请求处理——Map、Model类型参数处理原理
七、请求处理——Map、Model类型参数处理原理
2022-08-05 05:16:00 【呆比特】
请求处理——Map、Model类型参数处理原理
首先,先说结论,当我们给参数位置写 Map和Model 时,Map,Model 里边的数据会被放在 request 的请求域中,相当于我们调用了 request.setAttribute() ,接下来我们就来测试一下
//测试接口
@GetMapping("/params")
public String testParam(Map<String,Object> map,
Model model,
HttpServletRequest request,
HttpServletResponse response){
map.put("hello","world666");
model.addAttribute("world","hello666");
request.setAttribute("message","HelloWorld");
Cookie cookie = new Cookie("c1","v1");
response.addCookie(cookie);
return "forward:/success";
}
@ResponseBody
@GetMapping("/success")
public Map success(@RequestAttribute(value = "msg",required = false) String msg,
@RequestAttribute(value = "code",required = false) Integer code,
HttpServletRequest request){
Object msg1 = request.getAttribute("msg");
Map<String,Object> map = new HashMap<>();
Object hello = request.getAttribute("hello");
Object world = request.getAttribute("world");
Object message = request.getAttribute("message");
map.put("reqMethod_msg",msg1);
map.put("annotation_msg",msg);
map.put("hello",hello);
map.put("world",world);
map.put("message",message);
return map;
}
发送请求测试结果
验证了上边的结论:
参数Map、Model、request都是给request域中放数据
可以使用 request.getAttribute(); 进行获取,或者页面使用EL表达式获取
现在我们已经验证了结论是正确的,那里边的原理是什么呢?接下来就是debug环节
上一篇分析过的这里就不在重复了,我们直接来带真正执行目标方法的地方

进入该方法
首先,第一个参数是一个map,寻找解析它的解析器为 MapMethodProcessor

拿到解析器之后,我们来看它如何进行参数解析
往下到 InvocableHandlerMethod 类 的如下地方

来到 HandlerMethodArgumentResolverComposite 类的 resolveArgument 方法

来到了 MapMethodProcessor 类的 resolveArgument 方法

它里边会从 mavContainer 也就是 ModelAndViewContainer 中拿到并返回一个 BindingAwareModelMap
这就是第一个参数map,接下来看第二个参数 model ,经过和上边一样流程的调试,发现虽然它的解析器是 ModelMethodProcessor ,但是最后走的还是 mavContainer

所以得出结论:Map、Model类型的参数,会返回 mavContainer.getModel();返回BindingAwareModelMap 是Model 也是 Map
这样的方式拿到所有的参数,然后执行目标方法
执行完目标方法后,来到 ServletInvocableHandlerMethod 类的 invokeAndHandle,我们目标方法中给map和model中加的数据就保存到了 mavContainer
其实执行目标方法完成后,所有的数据都被放到了ModelAndViewContainer ,里边包含要去的地方 view 和 数据 model ,后边都是在处理它

然后继续下一步, ServletInvocableHandlerMethod 类 调用了 handleReturnValue ,传入了我们的 mavContainer

接下来一堆堆 mavContainer 的处理,处理完之后回到 DispatcherServlet 类,来到下边的 processDispatchResult 处理最终结果,处理完之后下边有一个 view.render(); 方法调用,还在 DispatcherServlet.class

进入这个方法,来到 AbstractView.class



我们也就验证了前边的结论:我们 Map 和 Model 类型的参数,其实本质上是一个东西,最终都被放入了 Request 请求域中。
到这里,Map、Model类型参数处理原理的原理我们就搞清楚了,下一篇再见!
边栏推荐
猜你喜欢
随机推荐
MySQL
ECCV2022 | RU&谷歌提出用CLIP进行zero-shot目标检测!
IDEA 配置连接数据库报错 Server returns invalid timezone. Need to set ‘serverTimezone‘ property.
【Kaggle项目实战记录】一个图片分类项目的步骤和思路分享——以树叶分类为例(用Pytorch)
SparkML-初探-文本分类
CVPR 2022 |节省70%的显存,训练速度提高2倍
SQL(1) - Add, delete, modify and search
基于Flink CDC实现实时数据采集(三)-Function接口实现
Spark ML学习相关资料整理
MaskDistill - Semantic segmentation without labeled data
用GAN的方法来进行图片匹配!休斯顿大学提出用于文本图像匹配的对抗表示学习,消除模态差异!
【22李宏毅机器学习】课程大纲概述
吞吐?带宽?傻傻分不清楚
flink部署操作-flink on yarn集群安装部署
网络信息安全运营方法论 (上)
flink基本原理及应用场景分析
全尺度表示的上下文非局部对齐
[Database and SQL study notes] 10. (T-SQL language) functions, stored procedures, triggers
Flutter 3.0升级内容,该如何与小程序结合
【数据库和SQL学习笔记】8.SQL中的视图(view)









