• Spring MVC之视图呈现


         在Spring MVC DispatcherServlet.doDispatch中请求在经过handler处理返回一个ModelAndView.

    那么ModelAndView又是如何最终转换为一个具体的View的呢?下面就对视图呈现部分作出一些简介。

    视图的渲染是处理一个请求的最后阶段:

    /**   根据ModelAndView中的视图名称进行解析,得到具体的视图对象
    	 * Render the given ModelAndView.
    	 * <p>This is the last stage in handling a request. It may involve resolving the view by name.
    	 * @param mv the ModelAndView to render
    	 * @param request current HTTP servlet request
    	 * @param response current HTTP servlet response
    	 * @throws ServletException if view is missing or cannot be resolved
    	 * @throws Exception if there's a problem rendering the view
    	 */
    	protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
    		// 确定请求的位置,并将位置信息应用到响应中
    		Locale locale = this.localeResolver.resolveLocale(request);
    		response.setLocale(locale);
    
    		View view;
    		// 如果只是一个视图的引用,则需要解析视图
    		if (mv.isReference()) {
    			// 解析视图名
    			view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request);
    			if (view == null) {
    				throw new ServletException(
    						"Could not resolve view with name '" + mv.getViewName() + "' in servlet with name '" +
    								getServletName() + "'");
    			}
    		}
    		else {
    			// 不需要解析视图名,从ModleAndView中获取实际的视图对象
    			view = mv.getView();
    			if (view == null) {
    				throw new ServletException("ModelAndView [" + mv + "] neither contains a view name nor a " +
    						"View object in servlet with name '" + getServletName() + "'");
    			}
    		}
    
    		// 将视图的渲染委派给视图对象,并通过HttpResponse把视图呈现给Http客户端
    		if (logger.isDebugEnabled()) {
    			logger.debug("Rendering view [" + view + "] in DispatcherServlet with name '" + getServletName() + "'");
    		}
    		view.render(mv.getModelInternal(), request, response);
    	}
    

      通过上面的代码可以发现对于视图的解析是使用如下方法:在该方法中遍历视图注册的视图解析器,如果优先级高的视图解析器可以解析出正确的视图对象,则直接放回视图对象。

    	/**
    	 * 将给定的视图名称解析成一个将被渲染的视图对象
             *  默认的实现要求调用所有的视图解析器。也可以基于特定的模型参数或请求参数使用自定义
             *  策略重写。 
    	 * <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</code> 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;
    	}

    自定义的一个JSON视图解析器:

    **
     *
     * @author zhangwei_david
     * @version $Id: JsonViewResolver.java, v 0.1 2014��11��30�� ����12:09:44 zhangwei_david Exp $
     */
    public class JsonViewResolver implements ViewResolver, Ordered {
    
        private static final Logger logger = LogManager.getLogger(JsonViewResolver.class);
    
        private int                 order  = Ordered.HIGHEST_PRECEDENCE;
        private UrlPathHelper       urlPathHelper;
    
        /**
         * @see org.springframework.web.servlet.ViewResolver#resolveViewName(java.lang.String, java.util.Locale)
         */
        public View resolveViewName(String viewName, Locale locale) throws Exception {
    
            RequestAttributes attrs = RequestContextHolder.getRequestAttributes();
            Assert.isInstanceOf(ServletRequestAttributes.class, attrs);
            HttpServletRequest request = ((ServletRequestAttributes) attrs).getRequest();
            String uri = urlPathHelper.getRequestUri(request);
            if (uri.contains(".json")) {
                LogUtils.info(logger, "Handler the Uri {0} and Return A JSON View", uri);
                return new MappingJacksonJsonView();
            }
            //
            return null;
        }
    
        /**
         * Getter method for property <tt>urlPathHelper</tt>.
         *
         * @return property value of urlPathHelper
         */
        public UrlPathHelper getUrlPathHelper() {
            return urlPathHelper;
        }
    
        /**
         * Setter method for property <tt>urlPathHelper</tt>.
         *
         * @param urlPathHelper value to be assigned to property urlPathHelper
         */
        public void setUrlPathHelper(UrlPathHelper urlPathHelper) {
            this.urlPathHelper = urlPathHelper;
        }
    
        /**
         * @see org.springframework.core.Ordered#getOrder()
         */
        public int getOrder() {
            return order;
        }
    
        /**
         * Setter method for property <tt>order</tt>.
         *
         * @param order value to be assigned to property order
         */
        public void setOrder(int order) {
            this.order = order;
        }
    
    }
  • 相关阅读:
    css选择符有哪些?哪些属性可以继承?优先级算法如何计算?内联和important哪个优先
    移动端重要的几个CSS3属性设置
    关于移动端的Click事件
    JS根据key值获取URL中的参数值,以及把URL的参数转换成json对象
    动态添加JS文件到页面
    JS 模拟C# 字符串格式化操作
    JS cookie 读写操作
    很好用的Tab标签切换功能,延迟Tab切换。
    SpringMVC 原理
    SpringMVC 三种异常处理方式
  • 原文地址:https://www.cnblogs.com/wei-zw/p/8797806.html
Copyright © 2020-2023  润新知