ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

22.Model、Map原理

2022-08-08 11:03:55  阅读:197  来源: 互联网

标签:Map 22 map request Model model 类中


Model 和 Map

为什么在Model和Map中放值传入后会出现在request的上面。

9.1、源码解析

  1. 准备测试代码

      @GetMapping("/goto")
      public String go(HttpServletRequest request,
      Map<String,Object> map,
      Model model){
       
      request.setAttribute("msg","传过来....");
      map.put("map","map hello word!!");
      model.addAttribute("model","model hello word!!");
       
      return "forward:success";
      }
       
      @ResponseBody
      @GetMapping("/success")
      public Map success(@RequestAttribute(value = "msg",required = false) String msg,
      HttpServletRequest request){
      Map<String,Object> hashMap = new HashMap<>();
       
      Object msg1 = request.getAttribute("msg");
      Object map = request.getAttribute("map");
      Object model = request.getAttribute("model");
       
      hashMap.put("map1",map);
      hashMap.put("model",model);
      hashMap.put("msg1",msg1);
       
      return hashMap;
      }
  2. 第一步进入DispatchServlet 的 doDispatch中

    • 主要的三步

        DispatchServlet类中的
        doDispatch方法
        // Determine handler for the current request.
        mappedHandler = getHandler(processedRequest);//获取反射的方法处理器
        // Determine handler adapter for the current request.
        //获取参数处理器
        HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
        // Actually invoke the handler.
        //反射执行方法和解析Model和Map
        mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
  3. 在获取参数阶段,解Model和Map

    • 获取Map 的 处理器器 MapMethodProcessor

    • 处理Map这个参数

        MapMethodProcessor类中的
        @Override
        @Nullable
        public Object resolveArgument(MethodParameter parameter,
        @Nullable ModelAndViewContainer mavContainer,
        NativeWebRequest webRequest,
        @Nullable WebDataBinderFactory binderFactory) throws Exception {
        Assert.state(mavContainer != null, "ModelAndViewContainer is required for model exposure");
         
        return mavContainer.getModel();
        }
         
        然后进入ModelAndViewContainer类中的
        private final ModelMap defaultModel = new BindingAwareModelMap();
        public ModelMap getModel() {
        if (useDefaultModel()) {
        return this.defaultModel;//获取ModelMap
        }
        ......
    • 把这个ModelMap对象返回

    • 获取Model的 处理器器 ModelMethodProcessor

    • 处理Model这个参数

        ModelMethodProcessor类中的
        @Override
        @Nullable
        public Object resolveArgument(MethodParameter parameter,
        @Nullable ModelAndViewContainer mavContainer,
        NativeWebRequest webRequest,
        @Nullable WebDataBinderFactory binderFactory) throws Exception {
         
        Assert.state(mavContainer != null, "ModelAndViewContainer is required for model exposure");
        return mavContainer.getModel();
        }
         
        然后进入ModelAndViewContainer类中的
        private final ModelMap defaultModel = new BindingAwareModelMap();
        public ModelMap getModel() {
        if (useDefaultModel()) {
        return this.defaultModel;//获取ModelMap 这个和那个Map获取的是同一个
        }
        ......
    • 把同一个ModelMap对象返回

  4. 反射调用方法

    由于是同一个对象所有 map 和 model中的值都样,所以往map和Model放值都一样

  5. 把model和map的数据放入request

    • 第一步
      ServletInvocableHandlerMethod类中
      invokeAndHandle方法
      //获取返回值的一个处理器
      try {
      this.returnValueHandlers.handleReturnValue(
      returnValue, getReturnValueType(returnValue),
      mavContainer, webRequest);
      }
      HandlerMethodReturnValueHandlerComposite类中的
      HandlerMethodReturnValueHandler方法 进行获取

    这里获取的ViewNameMethodReturnValueHandler这个处理器

    • 第二步

      把Map和 Model携带的参数和返回值(路径)进行整合为ModelAndView

      RequestMappingHandlerAdapter类中
      handleInternal方法
      ...
      ModelAndView mav;
      ...
      mav = invokeHandlerMethod(request, response, handlerMethod);
      ...

    • 第三步

      准备派发和放入参数

        DispatchServlet类中的
        doDispatch方法
        render(mv, request, response);
        view.render(mv.getModelInternal(), request, response);
         
        AbstractView类中的
        render方法
        //把BindingAwareModelMap的参数封装为Map
        Map<String, Object> mergedModel = createMergedOutputModel(model,
        request, response);
        prepareResponse(request, response);
        //准备方法和放入参数到reques中
        renderMergedOutputModel(mergedModel, getRequestToExpose(request),
        response);
        InternalResourceView类中的
        renderMergedOutputModel
        // Expose the model object as request attributes.
        exposeModelAsRequestAttributes(model, request);//把参数放入到request中
        AbstractView类中的
        //把参数放入到原生的request域中
        protected void exposeModelAsRequestAttributes(Map<String, Object> model,
        HttpServletRequest request) throws Exception {
        model.forEach((name, value) -> {
        if (value != null) {
        request.setAttribute(name, value);
        }
        else {
        request.removeAttribute(name);
        }
        });
        }

标签:Map,22,map,request,Model,model,类中
来源: https://www.cnblogs.com/55zjc/p/16561043.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有