Spring MVC 视图解析器

作者:範宗雲 来源:原创 发布时间:2015-04-05 归档:springmvc

开发环境 : JDK 7 Maven 3 Tomcat 7 Spring 4.1.5 Eclipse Luna
spring mvc 控制器里的所有处理方法的逻辑视图 ( 通过返回一个 String, View, ModelAndView 等 ) 由视图解析器来解析。spring mvc 支持多种视图技术, 并提供了多种视图解析器。
1.UrlBasedViewResolver
			<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
			  <property name="prefix" value="/WEB-INF/pages/" />
			  <property name="suffix" value=".jsp" />
			  <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
			</bean>
			
viewClass 项是必须的, 常用的有 :
org.springframework.web.servlet.view.JstlView
org.springframework.web.servlet.view.InternalResourceView
org.springframework.web.servlet.view.velocity.VelocityView
org.springframework.web.servlet.view.freemarker.FreeMarkerView
InternalResourceView 用于渲染 JSP 视图, JstlView 是 InternalResourceView 的一个扩展类, 用于显式的支持 JSTL。VelocityView 用于渲染 velocity 视图, FreeMarkerView 用于渲染 freemarker 视图。
UrlBasedViewResolver 支持 "redirect:" 和 "forward:" 前缀, 以完成重定向和转发的动作。每个逻辑视图名称被解析成 :prefix + [logical-view
-name] + suffix, 如逻辑视图名称为 home, 则视图的逻辑位置为 :/WEB-INF/pages/home.jsp, 并通过创建一个具体的 viewClass 实例来渲染该视图。
2.InternalResourceViewResolver
			<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
			  <property name="prefix" value="/WEB-INF/pages/" />
			  <property name="suffix" value=".jsp" />
			</bean>
			
InternalResourceViewResolver 是 UrlBasedViewResolver 的一个扩展类, 它使用 InternalResourceView 来渲染视图。
3.FreeMarkerViewResolver
			<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
			  <property name="templateLoaderPath" value="/WEB-INF/pages/" />
			  <property name="freemarkerSettings">
			    <props>
			      <!-- 检查模板是否被更新, 单位为秒。0 代表不缓存, 每次都重新加载 -->
			      <prop key="template_update_delay">0</prop>
			      <!-- 日期格式 -->
			      <prop key="date_format">yyyy-MM-dd</prop>
			      <!-- 日期时间格式 -->
			      <prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop>
		        </props>
		      </property>
		    </bean>
		    
		    <bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
		      <property name="suffix" value=".ftl" />
		      <property name="contentType" value="text/html;charset=UTF-8"/>
		    </bean>
			
FreeMarkerViewResolver 是 UrlBasedViewResolver 的一个扩展类, 它使用 FreeMarkerView 来渲染视图。使用 freemarker 视图技术需要引入 spring-context-support 及 freemarker 依赖。
			<dependency>
		      <groupId>org.springframework</groupId>
		      <artifactId>spring-context-support</artifactId>
		      <version>${spring.version}</version>
		    </dependency>
		    <dependency>
		      <groupId>org.freemarker</groupId>
		      <artifactId>freemarker</artifactId>
		      <version>${freemarker.version}</version>
		    </dependency>
			
4.VelocityViewResolver
			<bean class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
		      <property name="resourceLoaderPath" value="/WEB-INF/pages/" />
		      <property name="configLocation" value="/WEB-INF/velocity.properties" />
		    </bean>
		    
		    <bean class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
		      <property name="suffix" value=".vm" />
		      <property name="contentType" value="text/html;charset=utf-8" />
		    </bean>
			
velocity.properties
			input.encoding = UTF-8
			output.encoding = UTF-8
			resource.loader = file
			file.resource.loader.cache = false
			file.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader
			
或者 :
		    <bean class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
		      <property name="resourceLoaderPath" value="/WEB-INF/pages/" />
		      <property name="velocityProperties">
		        <props>
		          <prop key="input.encoding">UTF-8</prop>
		          <prop key="output.encoding">UTF-8</prop>
		          <prop key="resource.loader">file</prop>
		          <prop key="file.resource.loader.cache">false</prop>
		          <prop key="file.resource.loader.class">org.apache.velocity.runtime.resource.loader.FileResourceLoader</prop>
		        </props>
		      </property>
		    </bean>
		    
		    <bean class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
		      <property name="suffix" value=".vm" />
		      <property name="contentType" value="text/html;charset=utf-8" />
		    </bean>
			
VelocityViewResolver 是 UrlBasedViewResolver 的一个扩展类, 它使用 VelocityView 来渲染视图。使用 velocity 视图技术需要引入 spring-context-support 及 velocity 依赖。
			<dependency>
		      <groupId>org.springframework</groupId>
		      <artifactId>spring-context-support</artifactId>
		      <version>${spring.version}</version>
		    </dependency>
		    <dependency>
		      <groupId>org.apache.velocity</groupId>
		      <artifactId>velocity</artifactId>
		      <version>${velocity.version}</version>
		    </dependency>
			
5.ContentNegotiatingViewResolver
			<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
		      <!-- 以路径扩展名确定请求的媒体类型, 如 info.json -> application/json, 默认为 true -->
		      <property name="favorPathExtension" value="true" />
		      <!-- 以参数确定请求的媒体类型, 如 info?format=json -> application/json, 默认为 false -->
		      <property name="favorParameter" value="true" />
		      <!-- 定义参数名, 默认的参数名为 format -->
		      <property name="parameterName" value="format"/>
		      <!-- 是否忽略 Http Accept Header, 默认为 false -->
		      <property name="ignoreAcceptHeader" value="false"/>
		      <!-- 请求的媒体类型映射 -->
		      <property name="mediaTypes">
		        <props>
		          <prop key="json">application/json</prop>
		          <prop key="xml">application/xml</prop>
		          <prop key="html">text/html</prop>
		        </props>
		      </property>
		      <!-- 设置默认的 content type -->
		      <property name="defaultContentType" value="text/html" />
		    </bean>
		    
		    <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
		      <property name="contentNegotiationManager" ref="contentNegotiationManager" />
		      <!-- 视图解析器 -->
		      <property name="viewResolvers">
		        <list>
		          <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
		          <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		            <property name="prefix" value="/WEB-INF/pages/" />
		            <property name="suffix" value=".jsp" />
		          </bean>
		        </list>
		      </property>
		      <!-- 默认的视图 -->
		      <property name="defaultViews">
		        <list>
		          <!-- json 视图 -->
		          <bean class= "org.springframework.web.servlet.view.json.MappingJackson2JsonView" />
		          <!-- xml 视图 -->
		          <bean class= "org.springframework.web.servlet.view.xml.MarshallingView">
		            <property name="marshaller">
		              <bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
		                <!-- 扫描的包 -->
		                <property name="packagesToScan" value="org.lychie.model" />
		              </bean>
		            </property>
		          </bean>
		        </list>
		      </property>
		    </bean>
			
Controller
			@RequestMapping(value = "/domain/info", method = GET)
			public String info(ModelMap model) {
				model.addAttribute("user", new User(1001, "lychie", "lychie@yeah.net"));
				return "info";
			}
			
User
			package org.lychie.model;

			import javax.xml.bind.annotation.XmlRootElement;
			
			@XmlRootElement(name="user")
			public class User {
			
				private int id;
				private String name;
				private String mail;
				
				public User() {
					
				}
				
				public User(int id, String name, String mail) {
					this.id = id;
					this.name = name;
					this.mail = mail;
				}
			
				//ignore setters and getters
				
			}
			
info.jsp
			<body>
		      <h2>
		      id : ${user.id}<br>
		      name : ${user.name}<br>
		      mail : ${user.mail}
		      </h2>
		    </body>
			
ContentNegotiatingViewResolver 用于支持同一资源的多种不同的表现形式, 如 jsp、json、xml 等。具体采用何种方式来表现, 取决于 Http Accept Header。如 :
Accept : application/xml, 则数据表现为 xml 格式
Accept : application/json, 则数据表现为 json 格式
GET /domain/info
			id : 1001
			name : lychie
			mail : lychie@yeah.net
			
GET /domain/info.xml 或 GET /domain/info?format=xml
			This XML file does not appear to have any style information associated with it. The document tree is shown below.
			<user>
			  <id>1001</id>
			  <name>lychie</name>
			  <mail>lychie@yeah.net</mail>
			</user>
			
GET /domain/info.json 或 GET /domain/info?format=json
			{"user":{"id":1001,"name":"lychie","mail":"lychie@yeah.net"}}
			

示例代码下载
spring-mvc-view-resolvers.zip