七、请求处理——Map、Model类型参数处理原理

请求处理——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类型参数处理原理的原理我们就搞清楚了,下一篇再见!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Anton丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值