设为首页 加入收藏

TOP

day04-视图和视图解析器(二)
2023-07-26 08:17:19 】 浏览:110
Tags:day04- 解析器
t; <property name="order" value="99"/> </bean> <!--4.加入两个常规的配置--> <!--支持SpringMVC的高级功能,比如:JSR303校验,映射动态请求--> <mvc:annotation-driven></mvc:annotation-driven> <!--将SpringMVC不能处理的请求,交给tomcat处理,比如css,js--> <mvc:default-servlet-handler/>
  • 测试,访问view.jsp,点击超链接

    image-20230207175529158
  • 成功跳转到 my_view.jsp

    image-20230207175601984
  • 后台输出如下:说明整个执行流程如图所示。

    image-20230207175629231
  • 2.3创建自定义视图的步骤

    1. 自定义一个视图:创建一个 View 的 bean,该 bean 需要继承自 AbstractView,并实现renderMergedOutputModel方法
    2. 并把自定义 View 加入到 IOC 容器中
    3. 自定义视图的视图解析器,使用 BeanNameViewResolver,这个视图解析器也需要配置到 ioc 容器文件中
    4. BeanNameViewResolver 的调用优先级需要设置一下,设置 order 比 Integer.MAX_VALUE 小的值,以确保其在默认的视图解析器之前被调用

    2.4Debug源码-自定义视图解析器执行流程

    自定义视图-工作流程:

    1. SpringMVC 调用目标方法,返回自定义 View 在 IOC 容器中的 id
    2. SpringMVC 调用 BeanNameViewResolver 视图解析器:从 IOC 容器中获取返回 id 值对应的 bean,即自定义的 View 的对象
    3. SpringMVC 调用自定义视图的 renderMergedOutputModel 方法,渲染视图
    4. 说明:如果 SpringMVC 调用 Handler 的目标方法时,返回的自定义 View ,在 IOC 容器中的 id 不存在,则仍然按照默认的视图解析器机制处理。

    Debug-01

    (1)在GoodsHandler的目标方法中打上断点:

    image-20230207181443199

    (2)点击debug,访问view.jsp,点击超链接,可以看到后台光标跳转到断点处:

    image-20230207182111043

    (3)在源码 BeanNameViewResolver 的 resolveViewName 方法处打上断点:

    image-20230207181949587

    (4)点击Resume,光标跳转到了这个断点处,viewName 的值就是自定义视图对象的 id:这里完成视图解析

    image-20230207182357898

    resolveViewName 方法如下:

    @Override
    @Nullable
    public View resolveViewName(String viewName, Locale locale) throws BeansException {
       //获取ioc容器对象
       ApplicationContext context = obtainApplicationContext();
       //如果容器对象中不存在 目标方法返回的自定义视图对象id
       if (!context.containsBean(viewName)) {
          // Allow for ViewResolver chaining...
          //就返回null,让默认的视图解析器处理该视图
          return null;
       }
       //判断自定义的视图是不是 org.springframework.web.servlet.View 类型
       if (!context.isTypeMatch(viewName, View.class)) {
          //如果不是
          if (logger.isDebugEnabled()) {
             logger.debug("Found bean named '" + viewName + "' but it does not implement View");
          }
          // Since we're looking into the general ApplicationContext here,
          // let's accept this as a non-match and allow for chaining as well...
          return null;
       }
       //如果是,就返回这个自定义视图对象
       return context.getBean(viewName, View.class);
    }
    
    image-20230207183628224

    (5)在自定义视图对象里打上断点:

    image-20230207183815264

    (6)点击 resume,光标跳转到该断点:在这里完成视图渲染,并转发到结果页面

    image-20230207183923620 image-20230207184246555

    (7)最后由 tomcat 将数据返回给客户端:

    image-20230207184459844

    2.5Debug源码-默认视图解析器执行流程

    将默认视图解析器的优先级调高:

    image-20230207184950399

    debug-02

    (1)仍然在GoodsHandler中添加断点:

    image-20230207192822730

    (2)浏览器访问 view.jsp,可以看到后台光标跳转到了断点处:

    image-20230207193027494

    (3)分别在默认视图解析器(InternalResourceViewResolver)和自定义视图解析器(BeanNameViewResolver) 中的方法中打上断点:

    image-20230207193313100 image-20230207193321152

    (4)点击resume,可以看到光标先跳到了默认视图解析器的 buildView 方法中:因为默认解析器的优先级在之前设置为最高。

    image-20230207193631707

    buildView 方法:

    @Override
    protected AbstractUrlBasedView buildView(String viewName) throws Exception {
       //根据目标方法返回的viewName创建一个View对象
       InternalResourceView view = (InternalResourceView) super.buildView(viewName);
       if (this.alwaysInclude != null) {
          view.setAlwaysInclude(this.alwaysInclude);
       }
       view.setPreventDispatchLoop(true);
       return view;
    }
    

    这个 View 对象的 url 是按照你配置的前缀和后缀,拼接完成的 url

    image-20230207194350281

    (5)之后就会到该View对象进行视图渲染,然后由Tomcat将数据返回给客户端。

    但是如果该url下没有/WEB-INF/pages/liView.jsp文件,就会报错:

    image-20230207195118671

    2.6Debug源码-自定义View不存在,会走默认视图解析机制

    视图解析器可以配置多个,按照指定的顺序来对视图进行解析。如果上一个视图解析器不匹配,下一个视图解析器就会去解析视图,以此类推:

    image-20230207195521100
    1. 在容器文件中,将默认的视图解析器调用优先级降低,提高自定义视图解析器的调用优先级。见2.2的容器文件配置

    2. 删除2.2中的自定义视图MyView.java。也就是说,自定义视图解析器解析目标方法返回的视图对象时,将会无法解析该视图,因为它不存在。

    3. 这时就会去调用下一个优先级的视图解析器,即默认视图解析器。

    debug-03

    (1)仍然在GoodsHandler中添加断点:

    image-20230207192822730

    (2)浏览器访问 view.jsp,可以看到后台光标跳转到了断点处:

    image-20230207193027494

    (3)在自定义的视图解析器 BeanNameViewResolver 中打上断点:

    image-20230207200552990

    (4)点击resume,可以看到光标跳转到该断点

    首页 上一页 1 2 3 4 下一页 尾页 2/4/4
    】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
    上一篇3.SpringSecurity+登录功能+jwt校.. 下一篇读Java实战(第二版)笔记04_用流..

    最新文章

    热门文章

    Hot 文章

    Python

    C 语言

    C++基础

    大数据基础

    linux编程基础

    C/C++面试题目