详解Spring MVC 4之ViewResolver视图解析器

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介:

 所有的We MVC框架都有一套它自己的解析视图的机制,Spring MVC也不例外,它使用ViewResolver进行视图解析,让用户在浏览器中渲染模型。ViewResolver是一种开箱即用的技术,能够解析JSP、Velocity模板和XSLT等多种视图。


    Spring处理视图最重要的两个接口是ViewResolver和View。ViewResolver接口在视图名称和真正的视图之间提供映射; 而View接口则处理请求将真正的视图呈现给用户。


    1.几种常见的ViewResolver视图解析器


    在Spring MVC 4控制器中,所有的处理方法必须返回一个逻辑视图名称,无论是显式的(返回String,View或ModelAndView)还是隐式的。Spring中的视图由视图解析器处理这个逻辑视图名称,Spring有以下几种视图解析器:


  AbstractCachingViewResolver:用来缓存视图的抽象视图解析器。通常情况下,视图在使用前就准备好了。继承改解析器就能够使用视图缓存。


  XmlViewResolver :XML视图解析器。它实现了ViewResolver接口,接受相同DTD定义的XML配置文件作为Spring的XML bean工厂。


  ResourceBundleViewResolver:它使用了ResourceBundle定义下的bean,实现了ViewResolver接口,指定了绑定包的名称。通常情况下,配置文件会定义在classpath下的properties文件中,默认的文件名字是views.properties。


    UrlBasedViewResolver:它简单实现了ViewResolver接口,它不用显式定义,直接影响逻辑视图到URL的映射。它让你不用任何映射就能通过逻辑视图名称访问资源。


    InternalResourceViewResolver:国际化视图解析器。


    VelocityViewResolver /FreeMarkerViewResolver:Velocity或FreeMarker视图解析器。


    ContentNegotiatingViewResolver:内容谈判视图解析器


    在JSP视图技术中,Spring MVC经常会使用 UrlBasedViewResolver视图解析器,该解析器会将视图名称翻译成URL并通过RequestDispatcher处理请求后渲染视图。


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


    假如我们配置了如上所示的URL视图解析器,我们返回了一个叫“favmvc”的视图名称,视图解析器就会将请求转发到RequestDispatcher,然后跳转到/WEB-INF/views/favmvc.jsp页面。


    假如我们想要在应用中使用不同的视图技术,我们就应该使用 ResourceBundleViewResolver。


<bean id="viewResolver"
       class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
   <property name="basename" value="views"/>
   <property name="defaultParentView" value="parentView"/></bean>


    ResourceBundleViewResolver对于每个要处理的视图,都会检查 ResourceBundle中basename的唯一性,它使用 [viewname].(class)作为视图类,[viewname].url作为视图的url。



    2. 链式视图解析器(Chaining ViewResolvers)


    Spring支持同时配置多个视图解析器,也就是链式视图解析器。这样,在某些情况下,就能够重写某些视图。如果我们配置了多个视图解析器,并想要给视图解析器排序的话,设定 order 属性就可以指定解析器执行的顺序。order的值越高,解析器执行的顺序越晚。


    下面代码所示的例子由两个视图解析器组成。 InternalResourceViewResolver总是最后一个执行,而 XmlViewResolver则指定解析XML视图(InternalResourceViewResolver不支持Excel视图)。


<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
   <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
   <property name="prefix" value="/WEB-INF/jsp/"/>
   <property name="suffix" value=".jsp"/></bean><bean id="excelViewResolver" class="org.springframework.web.servlet.view.XmlViewResolver">
   <property name="order" value="1"/>
   <property name="location" value="/WEB-INF/views.xml"/></bean><!-- in views.xml --><beans>
   <bean name="report" class="org.springframework.example.ReportExcelView"/></beans>


    如果视图解析器没有指定视图的话,Spring就会检查其它的视图解析器,直到有一个完整的包含视图的视图解析器。如果一个完整的视图解析器也没有找到的话,Spring就会抛出 ServletException。


    视图解析器规定如果没有找到视图就返回null。但不是所有的视图解析器都这么做,因为在某些情况下,解析器并不能检测是否存在视图。比如InternalResourceViewResolver在内部使用RequestDispatcher时,调度转发是判断JSP是否存在的唯一方法,但该action却只能执行一次。VelocityViewResolver和其它的一些解析器也这样,区分这些视图解析器能否在找不到视图的情况下返回null,最好的方法就是看官方文档中它是否支持了。由于 InternalResourceViewResolver总会返回视图,在视图链中使用InternalResourceViewResolver就能让你避免这些问题。


    3.  重定向视图


    在controller控制器中强制重定向的方法就是创建并返回Spring的RedirectView实例。在这种情况下,DispatcherServlet不再使用正常的视图机制,因为它已经返回了重定向视图,DispatcherServlet只是告诉视图去显示。


    RedirectView会调用 HttpServletResponse.sendRedirect()方法,然后它就作为HTTP重定向返回给客户端浏览器。默认情况下,所有的模板属性变量都认为是重定向URL,其余的属性自动附加为查询参数。


    redirect前缀


    尽管RedirectView工作机制很好,但如果控制器本身创建RedirectView时,毫无疑问控制器本身知道该如何重定向。这样做并不好,控制器不应该关心响应如何处理,它只是处理被注入的视图名称。


    当我们在返回视图名称时,如果使用了“redirect:”前缀(如“redirect : /login”),UrlBasedViewResolver视图控制器会识别这是一次特殊的重定向,并把redirect后面的视图名称当做重定向的地址。


    假如我们在http://favccxx.com应用中返回“redirect:/favboy”视图时, 系统会重定向到http://favccxx.com/favboy。但如果我们返回了“redirect:http://favsoft.me”这样的视图时,系统会重定向到http://favsoft.me的视图上。


    forward前缀


    forward前缀视图是另一种通过URLBasedViewResolver机制处理到的转向机制,它在视图名称周围创建InternalResourceView,因此这个前缀跟InternalResourceViewResolver和InternalResourceView无关。但这个前缀在你想使用其它视图技术但想强制通过Servlet/JSP引擎处理资源进行转向时是有用的。

    

    redirect与forward的区别    


    redirect方式相当 于"response.sendRedirect()".这种方式外部特征就是浏览器地址栏最后显示的路径是转发后的新的路径.工作方式是这样的,服务器端会首先发一个response给浏览器,然后浏览器收到这个response后再发一个requeset给服务器,然后服务器发新的response给浏览器。这时页面收到的request是一个新从浏览器发来的.这种方式的结果是:


    A.在转发前后有两个不同的request对象,转发前后的两个控制器在request上的参数(request.getParameter())和request属性(request.getAttribute())不能共享。


    B.如果转发前后的两个控制器都配置在spring 拦截器范围内,这样拦截器会拦截前后两个request,即会拦截两次。


    C.最后返回到浏览器后,因为地址栏显示的是转发后的url,所以刷新页面时只会执行后面的url映射的控制器。


    forward方式相当于 request.getRequestDispatcher().forward(request,response) .这种方式的外部特征是浏览器地址显示的路径是转发前的路径。工作方式是这样,forward 发生在服务器内部,在前一个控制器处理完毕后,直接进入下一个控制器处理,并将最后的response发给浏览器。这种方式的结果是:


    A.转发前后是同一个request,后一个控制器可共享前一个控制器的参数与属性。


    B.因为是同一个request,拦截器只会拦截前一个url,如果前一个url在映射时未配置到拦截器拦截,则拦截后一个url,即只拦截一次。


    C.最后返回到浏览器后,因为地址栏显示的是转发前的url,所以刷新页面时会依次执行前后两个控制器。


   总结:本文介绍了Spring MVC 4中常见的几种视图解析器,以及如何配置视图解析器包括链式视图解析器,最后除了正常视图映射机制外,我们还能够通过redirect/forward视图转向机制完成视图的重定向。本文偏向原理性介绍,关于视图解析机制在工作中的使用,并没有做过多的介绍,目的是让读者能够了解ViewResolver的工作机制。





本文转自 genuinecx 51CTO博客,原文链接:http://blog.51cto.com/favccxx/1585720,如需转载请自行联系原作者
目录
相关文章
|
22天前
|
前端开发 Java 开发者
Spring MVC中的请求映射:@RequestMapping注解深度解析
在Spring MVC框架中,`@RequestMapping`注解是实现请求映射的关键,它将HTTP请求映射到相应的处理器方法上。本文将深入探讨`@RequestMapping`注解的工作原理、使用方法以及最佳实践,为开发者提供一份详尽的技术干货。
67 2
|
22天前
|
前端开发 Java Spring
探索Spring MVC:@Controller注解的全面解析
在Spring MVC框架中,`@Controller`注解是构建Web应用程序的基石之一。它不仅简化了控制器的定义,还提供了一种优雅的方式来处理HTTP请求。本文将全面解析`@Controller`注解,包括其定义、用法、以及在Spring MVC中的作用。
40 2
|
23天前
|
前端开发 Java Maven
深入解析:如何用 Spring Boot 实现分页和排序
深入解析:如何用 Spring Boot 实现分页和排序
47 2
|
25天前
|
Java 开发者 Spring
Spring AOP深度解析:探秘动态代理与增强逻辑
Spring框架中的AOP(Aspect-Oriented Programming,面向切面编程)功能为开发者提供了一种强大的工具,用以将横切关注点(如日志、事务管理等)与业务逻辑分离。本文将深入探讨Spring AOP的底层原理,包括动态代理机制和增强逻辑的实现。
35 4
|
22天前
|
前端开发 Java 开发者
Spring MVC中的控制器:@Controller注解全解析
在Spring MVC框架中,`@Controller`注解是构建Web应用程序控制层的核心。它不仅简化了控制器的定义,还提供了灵活的请求映射和处理机制。本文将深入探讨`@Controller`注解的用法、特点以及在实际开发中的应用。
57 0
|
1月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
71 2
|
2月前
|
缓存 Java 程序员
Map - LinkedHashSet&Map源码解析
Map - LinkedHashSet&Map源码解析
76 0
|
2月前
|
算法 Java 容器
Map - HashSet & HashMap 源码解析
Map - HashSet & HashMap 源码解析
62 0
|
2月前
|
存储 Java C++
Collection-PriorityQueue源码解析
Collection-PriorityQueue源码解析
66 0
|
2月前
|
安全 Java 程序员
Collection-Stack&Queue源码解析
Collection-Stack&Queue源码解析
86 0

推荐镜像

更多
下一篇
DataWorks