0
点赞
收藏
分享

微信扫一扫

视图解析器与视图的底层原理

是归人不是过客 2022-03-18 阅读 36
javajava-ee

视图解析器与视图的底层原理

看完一遍尚硅谷的视频后自己琢磨,不懂就继续看视频,内容可能多有漏洞,如有不对,还望大佬们斧正
简单的控制器方法,实现页面的跳转以及添加错误信息。

  @PostMapping("/login")
   public String main(User user, HttpSession session, Model model) {
       if(user.getUserName().length()>0&&(user.getPassword().equals("123456"))) {
           //登陆成功重定向main页面
           session.setAttribute("loginuser",user);
           return "redirect:/main.html";
       }else{
           //输入错误信息,添加提示信息给msg并添加request域中
           model.addAttribute("msg","账号或者密码错误");
           return "login";
       }
   }

   @GetMapping("/main.html")
   public String mainPage(){
       return "main";
   }

同时在判断userName和password的if方法处和doDispatch打断点,进行debug调试
在这里插入图片描述

  • 在提交登录请求之后,并不是直接使用doDispatch方法,在其之前有:run、service、invoke、process、doFilter、internalDoFilter、doPost、processRequest、doDispatch方法。

  • 此时经历过一系列方法之后,此时的request域中已经获取到了当前请求
    在这里插入图片描述

  • 之后获取当前请求的处理器
    在这里插入图片描述

  • 之后获取处理器的适配器
    在这里插入图片描述

  • 然后从request中获取请求的方法,post请求,不进入以下if中的方法,而是在之后执行适配器的执行方法。

  • 执行目标方法返回ModelAndView对象
    在这里插入图片描述

  • handle方法的内容
    在这里插入图片描述

  • 再次进入handleInternal
    在这里插入图片描述

  • 可见,首先checkRequest判定我们是否支持request方法,而后判断此时的session是否为同步session,显示并不是,所以之后执行invokeHandlerMethod方法;

  • 进入目标方法,先是数据绑定工厂,此处不深追

  • ServletInvocableHandlerMethod. 它是对 InvocableHandlerMethod 的扩
    展,它增加了 返回值和响应状态码的处理 ,另外在
    ServletInvocableHandlerMethod 有个内部类ConcurrentResultHandlerMethod 继承于它,支持 异常调用结果 处理, Servlet 容器下 Controller 在查找适配器时发起调用的最终就是 ServletInvocableHandlerMethod 。

  • ModelFactory是用来维护Model的,具体包含两个功能
    (1)初始化Model
    (2)处理器执行后将Model中相应的参数更新到SessionAttributes中

  • if中是参数处理器和返回值处理器

在这里插入图片描述

  • 之后经过一系列的初始化操作将请求携带的信息给到相应的对象中

在这里插入图片描述

  • 在数据成功匹配之后hanle方法执行。可见实际上是invokeAndHandle运作
  • 之后returnValue是之前的model等等的所有数据
    在这里插入图片描述
    在这里插入图片描述
  • 然后是返回值的解析
    在这里插入图片描述
  • 首先是返回值处理器的寻找,在14个处理器中通过for循环遍历,判断返回值类型是否与处理器所处理的一致

在这里插入图片描述

  • 寻找handler,这个可以处理字符串参数
    在这里插入图片描述
    在这里插入图片描述
  • 处理参数的具体方法:首先将returnValue转为字符串然后mavContainer存放,接着isRedirectViewName判断此时是否是需要重定向的页面

在这里插入图片描述

  • isRedirectViewName判断路径前缀是否是redirect:

在这里插入图片描述

  • 在方法执行完后,所有的参数此时都在mavContrainer中。同时,假如方法参数中有一个自定义类型的参数对象(从请求参数中确定的),就会把他重新放在ModelAndViewContrainler中

在这里插入图片描述

  • 然后返回mav,将视图地址和数据放在ModelAndView对象中,此时handle方法执行完毕,mv=mav。

在这里插入图片描述
在这里插入图片描述

  • 在接下来执行过程中会执行applyDefaultViewName,该方法是,在mv中没有视图的值,就给其一个默认的视图地址。

在这里插入图片描述
在这里插入图片描述

  • 接下来是处理派发结果processDispatchResult(决定页面该如何响应)在这里插入图片描述

  • render(mv, request, response);该方法执行视图的渲染

  • 根据方法的String返回值得到view对象(相当于定义了页面的渲染逻辑)

在这里插入图片描述

  • 所有的视图解析器尝试是否根据当前返回值得到view对象
    在这里插入图片描述
  • 根据返回值获取RedirectView

在这里插入图片描述
在这里插入图片描述

  • resolveViewName该方法首先创建一个view,然后传参给新建立的view,再判断viewname的前缀;然后分别再进行处理
  • 得到redirect:/main.html–>Thymeleaf new Redirect()
  • ContentNegotiationViewResolver里面包含了下面的所有的视图解析器,其在内部还是利用所有视图解析器得到对象。RedirectView
  • RedirectView如何渲染(重定向到一个页面):
    1、获取目标url地址
    2、response.sendRedirect(encodeURL);
    至此,页面重定向就此解决,在处理过程中,如果方法还有其他注解也会一一的进行解析和处理
举报

相关推荐

0 条评论