• [springMVC学习]6、视图解析器,debug源码


    目录

    简介

    默认视图解析器

    自定义视图

    Debug源码

    自定义视图Debug

    默认视图Debug

    总结


    简介

            在springmvc中,我们返回的数据默认都会构成ModelAndView,这个View就是要跳转的页面,如果我们返回一个字符串,那么该字符串就会被默认视图解析器解析作为转发路径。当然,视图解析器也可以自定义。


    默认视图解析器

            springmvc中默认视图解析器是InternalResourceViewReslover,用于解析handler返回的信息。

             看类图可以发现它继承了UrlBasedViewResolver,下面来看看InternalResourceViewReslover和UrlBasedViewResolver这2个类的注释

             InternalResourceViewReslover注释大概意思就是建议我们将文件放到WEB-INF目录下,这样可以阻止直接请求访问。还有一个注意事项就是  InternalResourceViewReslover是作为最后一个解析器进行解析的。注意:springmvc包含多种解析器,还可能有自定义解析器。下面再看下UrlBasedViewResolver这个类注释

             通过类上面的注释,我们可以知道UrlBasedViewResolver会将返回值作为视图名称解析解析,寻找项目中的资源,同时还会添加前缀和后缀,前缀和后缀都是自定义的。该类还会解析返回值十分是forward:或者redirect:开头的,如果是,那么就会进行转发或者重定向到对应资源,而不是进行标准视图解析。

            为了测试方便,创建一个jsp页面 

    1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    2. <html>
    3. <head>
    4. <title>成功title>
    5. head>
    6. <body>
    7. <h1>测试成功!!!h1>
    8. body>
    9. html>

             通过上面的注释,可以知道,我们可以给默认视图解析器配置一个prefix和suffix,下面在配置文件中进行配置

    1. <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    2. <property name="prefix" value="/WEB-INF/pages/"/>
    3. <property name="suffix" value=".jsp"/>
    4. bean>

             下面编写java代码进行测试

    1. @RequestMapping("/view")
    2. @Controller
    3. public class ViewController {
    4. @RequestMapping("/f1")
    5. public String f1() {
    6. System.out.println("f1.....");
    7. return "success";
    8. }
    9. }

             上面代码就可以知道,f1方法会转发到/WEB-INF/pages/success.jsp页面,使用postman进行测试

             测试没有问题,下面写法就是转发和重定向,就不测试了

    1. @RequestMapping("/f2")
    2. public String f2() {
    3. System.out.println("f2.....");
    4. //会转发到f1,以当前路径为参考,不会添加prefix和suffix,
    5. return "forward:f1";
    6. }
    7. @RequestMapping("/f3")
    8. public String f3() {
    9. System.out.println("f3.....");
    10. //会重定向到f1,以当前路径为参考,不会添加prefix和suffix,
    11. return "redirect:f1";
    12. }

    自定义视图

            通过上面的默认视图,可以发现局限性是很大的,这是,我们就可以自定义视图,下面来进行说明。

            自定义视图主要分为4个部分,如下

    1. 创建类继承AbstractView,实现renderMergedOutputModel 方法
    2. 将其添加进spring容器,设置id
    3. 配置自定义视图解析器,该解析器名称是BeanNameViewResolver,它会处理我们的视图
    4. 将自定义解析器优先级调高

            下面就是具体的代码实现,先创建自己的视图解析

    1. @Component("myView")
    2. public class MyView extends AbstractView {
    3. @Override
    4. protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception {
    5. System.out.println("自定义视图---调用了MyView的renderMergedOutputModel方法");
    6. String url = "/WEB-INF/pages/success.jsp";
    7. request.getRequestDispatcher(url).forward(request, response);
    8. }
    9. }

            配置自定义视图的解析器,设置其优先级,通过order设置,默认是Integer.MAX_VALUE,值越小,优先级越高。

            上面就是该类的主要注释,可以发现该类就是用来解析自定义视图的 

    1. <bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
    2. <property name="order" value="99"/>
    3. bean>

            然后创建handler进行测试,我们直接返回视图的id即可,id就是直接的视图在spribg容器中的名称

    1. @RequestMapping("f4")
    2. public String f4() {
    3. System.out.println("f4.....");
    4. return "myView";
    5. }

             访问该handler,自定义视图没有问题

            可以发现,使用十分简单,下面就开始debug源码,看底层是如何实现的。


    Debug源码

    自定义视图Debug

            如果不知道底层原理,那么出现bug时就很难解决了,下面就开始debug吧。先debug自定义视图部分

            进入该方法,发现就是判断我们是否设置了返回的视图,继续往下执行 

             进入解析视图方法,查看如何实现的

            下面就是所有的解析器

            进入自定义视图的resolveViewName

            到这里,自定义视图就debug完成了,下面开始默认视图的 

     默认视图Debug

            debug前面部分都是相同的,下面从遍历所有解析器开始debug

             请求的是f1方法,会返回success的视图名称,下面就是自定义视图先进行解析,因为优先级更高

            然后就是默认视图解析,我们进行默认视图的resolveViewName方法

             由于我们返回的值不是redirect和forward,会继续调用父类的createView方法,一直往里面追,直到看见构建最终的视图url

             到这里,默认视图的debug也完成了


    总结

            自定义视图还是比较简单的,容易理解,为了加深理解,可以自己进行debug 

  • 相关阅读:
    ifconfig命令的使用
    好用的开源项目地址
    dedecms织梦复制模型报错系统找不到你所指定的表
    Python+大数据-Hadoop生态-hadoop(一)--大数据导论、Apache Zookeeper
    C++Qt开发——操作MySQL数据库
    离线强化学习(Offline RL)系列7: (状态处理)Koopman-Q学习:通过动力学对称性的状态空间数据增强方法
    Oracle/PLSQL: To_Timestamp_Tz Function
    vue3 - ref和reactive的区别
    RobotFrameWork自动化测试环境搭建
    selenium 下载文件取消安全下载的方法
  • 原文地址:https://blog.csdn.net/m0_51545690/article/details/126013811