• 十、视图解析原理与源码分析


    视图解析原理与源码分析

      前边已经学习完了SpringBoot请求如何处理、参数如何解析,响应如何处理,如何处理返回值。接下来这篇,主要通过源码,逐步分析SpringBoot中的视图解析原理。

       我们知道,所有的请求都是从 DispatcherServlet 开始的,现在来到这个类的 doDispatch 方法加上断点,来分析一下页面的跳转过程。

    @PostMapping("/login")
        public String main(User user, HttpSession session, Model model){
    
            if(StringUtils.hasLength(user.getUserName()) && "123456".equals(user.getPassword())){
                //把登陆成功的用户保存起来
                session.setAttribute("loginUser",user);
                //登录成功重定向到main.html;  重定向防止表单重复提交
                return "redirect:/main.html";
            }else {
                model.addAttribute("msg","账号密码错误");
                //回到登录页面
                return "login";
            }
        }
    
    @GetMapping("/main.html")
        public String mainPage(HttpSession session,Model model){
        	return "main";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    首先,来到登录页输入正确的密码进行登录,请求来到 doDispatch 方法,大概过一下之前学过的流程
    在这里插入图片描述
    下一步
    在这里插入图片描述
    下一步
    在这里插入图片描述
    step into 进入方法,到 RequestMappingHandlerAdapter.class 的 invokeHandlerMethod 执行目标方法
    在这里插入图片描述
    一直下一步,让执行目标方法

    在这里插入图片描述
    在这里插入图片描述
    下一步,让目标方法执行完,来到 ServletInvocableHandlerMethod.class 的 invokeAndHandle 方法
    在这里插入图片描述
    继续往下走,解析返回值,找到处理我们返回值的处理器 ViewNameMethodReturnValueHandler

    在这里插入图片描述
    继续往下,进入 ViewNameMethodReturnValueHandler 的 handleReturnValue,在目标方法处理的过程中,所有数据和视图地址,都会被放在 ModelAndViewContainer 里面。

    在这里插入图片描述
    方法执行完以后所有的东西就都在 ModelAndViewContainer 里边了,如果方法的参数是一个自定义类型对象(从请求参数中确定的),也会把他重新放在 ModelAndViewContainer

    在这里插入图片描述
    继续下一步让方法执行完,可以发现,任何目标方法执行完成以后都会返回 ModelAndView 保存了数据和视图地址

    在这里插入图片描述
    而且,就算你方法没有返回值,它也会给你默认一个跳转页,比如我们没有返回值,它就会拿到原生的request,查看当前的请求是什么,然后当做跳转的页面

    在这里插入图片描述
    到现在为止,我们的页面还没有跳转,继续往下走,来到一个 processDispatchResult 方法,翻译的话就是处理派发结果,就是它来决定页面如何响应的

    进入这个方法,开始视图解析原理

    在这里插入图片描述
    进入方法
    在这里插入图片描述
    View对象定义了页面的渲染逻辑,我们来看看View对象是如何获取的
    在这里插入图片描述
    进入 resolveViewName 方法
    在这里插入图片描述
    我们的返回值为 redirect:/main.html ,所以最终拿到了一个 RedirectView ,它的效果其实就是 重定向到一个页面

    视图解析器只有一个作用,就是获取View对象

    得到视图对象之后,视图对象会调用它的 render 方法
    在这里插入图片描述
    进入 renderMergedOutputModel ,真正的逻辑方法

    protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws IOException {
    		//第一步,获取目标url地址
            String targetUrl = this.createTargetUrl(model, request);
            targetUrl = this.updateTargetUrl(targetUrl, model, request, response);
            RequestContextUtils.saveOutputFlashMap(targetUrl, request, response);
            //重定向
            this.sendRedirect(request, response, targetUrl, this.http10Compatible);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述
    最终就是调用了我们使用servlet的最原始的方法

    总结视图解析

    返回值以 forward: 开始: new InternalResourceView(forwardUrl);   -->  转发
    	request.getRequestDispatcher(path).forward(request, response); 
    	
    返回值以 redirect: 开始: new RedirectView()  -->  render就是重定向 
     
    返回值是普通字符串: new ThymeleafView()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    OVER(∩_∩)~

  • 相关阅读:
    Spring security5.5.7出现Encoded password does not look like BCrypt异常
    C- ssize_t & size_t
    一行代码优化 pdfjs 加载大文件的pdf 速度
    [Redis]-四种部署方式
    MATLAB中M文件编写
    操作系统知识学习——操作系统的特征、功能和结构设计简析
    Thymeleaf介绍及其在Spring Boot中的使用
    【原创】mitmdump 安装证书至手机系统证书
    【AI视野·今日NLP 自然语言处理论文速览 第四十三期】Thu, 28 Sep 2023
    Redis 常用命令和基本数据结构(数据类型)
  • 原文地址:https://blog.csdn.net/NICK_53/article/details/126092000