SpringMVC组件之ViewResolver

ViewResolver

作用:根据viewName找到view对象

SpringMVC用于处理视图最重要的两个接口是ViewResolver和View。ViewResolver的主要作用是把一个逻辑上的视图名称解析为一个真正的视图,SpringMVC中用于把View对象呈现给客户端的是View对象本身,而ViewResolver只是把逻辑视图名称解析为对象的View对象。View接口的主要作用是用于处理视图,然后返回给客户端。

ViewResolver的提供的接口的主要功能是生成View对象,源码如下:

    public interface ViewResolver {  

        /** 
         * Resolve the given view by name. 
         * <p>Note: To allow for ViewResolver chaining, a ViewResolver should 
         * return {@code null} if a view with the given name is not defined in it. 
         * However, this is not required: Some ViewResolvers will always attempt 
         * to build View objects with the given name, unable to return {@code null} 
         * (rather throwing an exception when View creation failed). 
         * @param viewName name of the view to resolve 
         * @param locale Locale in which to resolve the view. 
         * ViewResolvers that support internationalization should respect this. 
         * @return the View object, or {@code null} if not found 
         * (optional, to allow for ViewResolver chaining) 
         * @throws Exception if the view cannot be resolved 
         * (typically in case of problems creating an actual View object) 
         */  
        View resolveViewName(String viewName, Locale locale) throws Exception;  

    }  

Spring为我们提供了非常多的视图解析器,下面将列举一些视图解析器。一句话概述下,不了解的麻烦看我写的详细的视图解析器链接
1.AbstractCachingViewResolver 基于缓存的抽象视图解析器
2.UrlBasedViewResolver 实现了缓存 提供了prefix suffix拼接的url视图解析器。
3、InternalResourceViewResolver 基于url 的内部资源视图解析器。
4.XmlViewResolver 基于xml的缓存视图解析器
5.BeanNameViewResolver beanName来自容器,并且不支持缓存。
6.ResourceBundleViewResolver 这个有点复杂,自己看后面的链接
7.FreeMarkerViewResolver、VolocityViewResolver 都基于url 但会解析成特定的view

如果对常见的ViewResolver不了解点这里—》

关于该接口的学习我们明白两件事就可以了
1.关于viewResolver的注册
2.resolveviewName方法的实现

首先第一个问题
它是在DispatcherServlet的init阶段完成的,简单了解下就可以

第二个问题
则是ViewResolver接口的resolveviewName方法
在开发的一套springMVC系统中是可以使用多个视图的,当然就需要配置多个视图解析器了,ViewResolverComposite简单来说就是使用简单的List来保存你配置使用的视图解析器。

iewResolverComposite中定义了两个变量:

(1)private final List viewResolvers = new ArrayList();用来存储所有的视图解析器

(2)private int order 用来配置视图解析器的使用顺序。

主要是一个视图解析器集合

public class ViewResolverComposite implements ViewResolver, Ordered, InitializingBean,  
            ApplicationContextAware, ServletContextAware {  

        //用来存储所有的视图解析器  
        private final List<ViewResolver> viewResolvers = new ArrayList<ViewResolver>();  
        //设置视图解析器的执行顺序  
        private int order = Ordered.LOWEST_PRECEDENCE;  


        //设置视图解析器  
        public void setViewResolvers(List<ViewResolver> viewResolvers) {  
            this.viewResolvers.clear();  
            if (!CollectionUtils.isEmpty(viewResolvers)) {  
                this.viewResolvers.addAll(viewResolvers);  
            }  
        }  

        //获取所有的视图解析器  
        public List<ViewResolver> getViewResolvers() {  
            return Collections.unmodifiableList(this.viewResolvers);  
        }  

        //设置执行顺序  
        public void setOrder(int order) {  
            this.order = order;  
        }  

        @Override  
        public int getOrder() {  
            return this.order;  
        }  

        @Override  
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {  
            for (ViewResolver viewResolver : this.viewResolvers) {  
                if (viewResolver instanceof ApplicationContextAware) {  
                    ((ApplicationContextAware)viewResolver).setApplicationContext(applicationContext);  
                }  
            }  
        }  

        @Override  
        public void setServletContext(ServletContext servletContext) {  
            for (ViewResolver viewResolver : this.viewResolvers) {  
                if (viewResolver instanceof ServletContextAware) {  
                    ((ServletContextAware)viewResolver).setServletContext(servletContext);  
                }  
            }  
        }  
        //初始化视图解析器  
        @Override  
        public void afterPropertiesSet() throws Exception {  
            for (ViewResolver viewResolver : this.viewResolvers) {  
                if (viewResolver instanceof InitializingBean) {  
                    ((InitializingBean) viewResolver).afterPropertiesSet();  
                }  
            }  
        }  
        //生成View对象  
        @Override  
        public View resolveViewName(String viewName, Locale locale) throws Exception {  
            for (ViewResolver viewResolver : this.viewResolvers) {  
                View view = viewResolver.resolveViewName(viewName, locale);  
                if (view != null) {  
                    return view;  
                }  
            }  
            return null;  
        }  

    }  solves链表遍历 找到一个能获取view对象的ViewResolver,并返回该view对象


/**
     * Resolve the given view name into a View object (to be rendered).
     * <p>The default implementations asks all ViewResolvers of this dispatcher.
     * Can be overridden for custom resolution strategies, potentially based on
     * specific model attributes or request parameters.
     * @param viewName the name of the view to resolve
     * @param model the model to be passed to the view
     * @param locale the current locale
     * @param request current HTTP servlet request
     * @return the View object, or {@code null} if none found
     * @throws Exception if the view cannot be resolved
     * (typically in case of problems creating an actual View object)
     * @see ViewResolver#resolveViewName
     */
    protected View resolveViewName(String viewName, Map<String, Object> model, Locale locale,
            HttpServletRequest request) throws Exception {

        for (ViewResolver viewResolver : this.viewResolvers) {
            View view = viewResolver.resolveViewName(viewName, locale);
            if (view != null) {
                return view;
            }
        }
        return null;
    }

然后看它的resolveViewName方法

接下来我们通过介绍常见InternalResourceViewResolver来对ViewResolver的运行流程有一个简单的了解和认识。

1、首先执行的流程开始在DispatcherServlet的render函数中,会调用resolverViewName来获取View对象。

    protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {  
            // Determine locale for request and apply it to the response.  

            ........  

            View view;  
            ........  
            //获得视图  
            view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request);  

            .......  
        }  

resolveViewName的主要工作就是从配置的所有视图解析器中查找一个可以生成View对象的视图解析器。

    protected View resolveViewName(String viewName, Map<String, Object> model, Locale locale,  
                HttpServletRequest request) throws Exception {  

            for (ViewResolver viewResolver : this.viewResolvers) {  
                View view = viewResolver.resolveViewName(viewName, locale);  
                if (view != null) {  
                    return view;  
                }  
            }  
            return null;  
        }  

这里选取的是InternalResourceViewResolver。其他的方法类似。

在InternalResourceViewResolver中的操作就是将viewName和locale设置到View对象中,这样就完成了View对象的创建。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值