• [Java] SpringMVC工作原理之三:ViewResolver


    一、ViewResolver

    根据视图的名称将其解析为 View 类型的视图,如通过 ModelAndView 中的视图名称将其解析成 View,View 是用来渲染页面的,也就是将 Model 填入模板中,生成 html 或其他格式的文件。

    可以设置多个解析策略,如可以根据 JSP 来解析,或者按照 Velocity 模版解析,如果设置了多个解析策略则可以通过 order 属性来设定其优先级,数值越小优先级越高,前面的视图解析器解析后就不会让后面的继续解析。默认的解析策略是 InternalResourceViewResolver,按照 JSP 页面来解析。ViewResolver 接口中的方法如下:

    • View resolveViewName(String viewName, Locale locale);

    1 带有缓存的 ViewResolver

    AbstractCachingViewResolver 是带有缓存的 ViewResolver,它每次解析时先从缓存里查找,如果找到视图就返回,没有就创建新的视图,且创建新视图的方法由其子类实现,具体代码如下所示:

    复制代码
    @Override
    public View resolveViewName(String viewName, Locale locale) throws Exception {
        // 是否启用缓存,可通过setCache()方法或setCacheLimit()方法开启缓存,是一个ConcurrentHashMap,默认缓存大小1024
        if (!isCache()) {
            return createView(viewName, locale);
        } else {
            // 得到 view 在缓存中的 key 值
            Object cacheKey = getCacheKey(viewName, locale);
            View view = this.viewAccessCache.get(cacheKey);
            // 如果没有找到 view 则创建,采用双重校验的方式进行安全创建
            if (view == null) {
                synchronized (this.viewCreationCache) {
                    view = this.viewCreationCache.get(cacheKey);
                    if (view == null) {
                        // 具体的创建方式由子类实现
                        view = createView(viewName, locale);
                        if (view == null && this.cacheUnresolved) {
                            view = UNRESOLVED_VIEW;
                        }
                        if (view != null) {
                            this.viewAccessCache.put(cacheKey, view);
                            this.viewCreationCache.put(cacheKey, view);
                        }
                    }
                }
            }
            return (view != UNRESOLVED_VIEW ? view : null);
        }
    }
    复制代码

    1.1 ResourceBundleViewResolver

    ResourceBundleViewResolver 根据 views.properties 文件来解析视图,这个文件位于 classpath 路径下,使用方式如下:

    <bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver">  
        <!-- 设定属性文件名为views -->  
        <property name="basename" value="views"></property>  
    </bean>  

    1.2 XmlViewResolver

    XmlViewResolver 根据 xml 文件来解析视图,使用方式如下:

    <bean class="org.springframework.web.servlet.view.XmlViewResolver">
        <property name="location">
            <value>/WEB-INF/spring-views.xml</value>
        </property>
    </bean>

    1.3 UrlBasedViewResolver

    UrlBasedViewResolver 提供了拼接 URL 的方式来解析视图,通过 prefix 属性拼接一个前缀,通过 suffix 属性拼接一个后缀,就得到了视图的 URL。还可以加入 redirect: 与 forword: 前缀,使用 redirect: 前缀会调用 HttpServletResponse对象的 sendRedirect() 方法进行重定向,使用 forword: 前缀会利用 RequestDispatcher的forword 方式跳转到指定的地址。另外,使用时还要指定 viewClass 属性,表示要解析成哪种 View,的使用方式如下:

    <bean  
       class="org.springframework.web.servlet.view.UrlBasedViewResolver">  
       <property name="prefix" value="/WEB-INF/" />  
       <property name="suffix" value=".jsp" />  
       <property name="viewClass" value="org.springframework.web.servlet.view.InternalResourceView"/>  
    </bean>  

    1.4 InternalResourceViewResolver 

    InternalResourceViewResolver 是 UrlBasedViewResolver 的子类,将 InternalResourceView 作为默认的 View 类,但如果当前classpath 中有 jstl 的 jar 包时则使用 JstlView 作为 view 来渲染。

    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
           <property name="prefix" value="/WEB-INF/jsp/" />
           <property name="suffix" value=".jsp" />
    </bean>

    2 其他的 ViewResolver

    2.1 BeanNameViewResolver

    BeanNameViewResolver 是通过视图名称去容器中获取对应的 view 对像,所以在使用前需要将 view 对象注册到容器中。它没有缓存,实现方式如下:

    复制代码
    @Override
    public View resolveViewName(String viewName, Locale locale) throws BeansException {
        ApplicationContext context = getApplicationContext();
        if (!context.containsBean(viewName)) {
            // Allow for ViewResolver chaining...
            return null;
        }
        if (!context.isTypeMatch(viewName, View.class)) {
            // 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);
    }
    复制代码
  • 相关阅读:
    互联网架构 高可用和高并发 (转)
    mysql数据库索引
    SQL小结
    limit小结
    JDK8 元空间
    OpenStack基础知识
    shell 发送所有内容到会话
    通过word给博客园发布文章教程
    centos7.4安装过程
    Zabbix 调整告警发送的内容格式
  • 原文地址:https://www.cnblogs.com/liuys635/p/10248804.html
Copyright © 2020-2023  润新知