• SpringMVC自定义视图完成步骤 和 视图解析的源码剖析


    自定义视图完成步骤:

    7.2.1自定义视图完成步骤

    1. 自定义视图**:** 创建一个 View bean, bean 需要继承自 AbstractView, 并实现

    renderMergedOutputModel 方法**.**

    2. 并把自定义 View 加入到 IOC 容器中

    3. 自定义视图的视图处理器,使用 BeanNameViewResolver**, 这个视图处理器也需要配置**

    ioc 容器

    4. BeanNameViewResolver 的调用优先级需要设置一下,设置 order Integer.MAX_VAL

    小的值**.** 以确保其在 InternalResourceViewResolver 之前被调用

     /**
      * 老师解读
      * 1. MyView继承了AbstractView, 就可以作为一个视图使用
      * 2. @Component(value = "myView"),该视图会注入到容器中, 名字/id是 myView
      */
     @Component(value = "hspView")
     public class MyView extends AbstractView {
         @Override
         protected void renderMergedOutputModel(Map model,
                                                HttpServletRequest request,
                                                HttpServletResponse response) throws Exception {
     ​
             //完成视图渲染
             //并且可以确定我们要跳转的页面 [请求转发] /WEB-INF/pages/my_view.jsp
             System.out.println("进入到自己的视图..");
     ​
             //老师解读
             //1. 下面就是进行请求转发到 /WEB-INF/pages/my_view.jsp
             //2. /WEB-INF/pages/my_view.jsp 会被springmvc解析
             //   /springmvc/WEB-INF/pages/my_view.jsp
             request.getRequestDispatcher("/WEB-INF/pages/my_view.jsp")
                     .forward(request, response);
     ​
         }
     }
     
     
         
     

    使用

     @RequestMapping(value = "/buy")
     public String buy() {
         System.out.println("------buy()-----");
         return "hspView";//填写自定义视图id
     }

    源码剖析:

    视图解析过程
    1.先到DispatcherServlet中央控制器, 根据视图解析的 优先级 执行对应的 视图解析器
     @Nullable
     protected View resolveViewName(String viewName, @Nullable Map model,
           Locale locale, HttpServletRequest request) throws Exception {
     ​
        if (this.viewResolvers != null) {
           for (ViewResolver viewResolver : this.viewResolvers) {//viewResolvers存放了两个视图解析器(1)InternalResourceViewResolver默认视图解析器   (2)BeanNameViewResolver自定义视图解析器
              View view = viewResolver.resolveViewName(viewName, locale);
              if (view != null) {//如果返回的视图为空,那么会继续遍历所有的视图解析器;
                  //注意:如果 默认视图解析器 优先级在前,那么不管怎样,它都不会再执行 自定义视图解析器 
                  //原因:默认视图解析器 一定会返回视图,因为它是通过传入的视图名build一个视图
                 return view;
              }
           }
        }
        return null;
     }
    2.若默认视图解析器在前,那么用 视图解析器 解析
     @Override
     protected AbstractUrlBasedView buildView(String viewName) throws Exception {
        InternalResourceView view = (InternalResourceView) super.buildView(viewName);//根据viewName创建视图
        if (this.alwaysInclude != null) {
           view.setAlwaysInclude(this.alwaysInclude);
        }
        view.setPreventDispatchLoop(true);
        return view;
     }

    注意:如果 默认视图解析器 优先级在前,那么不管怎样,它都不会再执行 自定义视图解析器 (因为:默认视图解析器 一定会返回视图,因为它是通过传入的视图名build一个视图)

    3.若自定义视图解析器在前
     public View resolveViewName(String viewName, Locale locale) throws BeansException {
        ApplicationContext context = obtainApplicationContext();//context实质上就类似于ioc容器
        if (!context.containsBean(viewName)) {//判断context(ioc)中是否有id为viewName的bean
           // Allow for ViewResolver chaining...
           return null;
        }
        if (!context.isTypeMatch(viewName, View.class)) {//判断context(ioc)中是否有id为viewName并实现View接口的bean
           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);
     }

    1.拿到context对象,实质上类似于ioc容器

    2.//判断context(ioc)中是否有id为viewName的bean, 没有就返回null; 有就接着往下走

    3.//判断context(ioc)中是否有id为viewName并实现View接口的bean 有就返回该视图 ,如果不存在传入的viewName对应的自定义视图,那么就返回null,接着走其他视图解析器

    视图渲染和响应
    1. 拿到view对象后, SpringMVC 调用自定义视图的 renderMergedOutputModel 方法渲染视图
  • 相关阅读:
    拯救pandas计划(24)——数据框形状的转换:​列转行,行转列
    2022年最新阿里Java高级岗200+面试题,能答出一般你就进了
    性能测试岗位能力模型
    【qemu逃逸】华为云2021-qemu_zzz
    Qt model/view 理解01
    安装mysql时出现:需要这两个包perl(Data::Dumper),perl(JSON)
    第一章 基础算法
    计算机组成原理 期末复习笔记
    SMTP发送邮件时抱No appropriate protocol错误分析和解决方案
    cocos2dx:CCOrbitCamera 实现精灵的球面翻转或类似翻书操作,以及翻转轨迹优化问题
  • 原文地址:https://blog.csdn.net/m0_59084856/article/details/132762009