spring视图解析——自定义解析器实例

第一种方式:

在基于SpringMVC的项目中有时需要同时使用多种视图格式,如jsp,velocity及freemarker等,通过不同的请求路径配置规则,映射到不同的视图文件。下面我提供一种思路,通过视图模板文件后缀名的方式来进行处理。例如:

@RequestMapping(value = "/hello") 
public String jspTest(HttpServletRequest request, ModelMap map) { 
    return "demo.jsp"; 

将通过”demo.jsp”的后缀自动使用jsp的视图解析器。

 

下面描述下详细思路:

 

一.自定义视图解析器

复制代码
package com.jeedev.common.web.springmvc.view;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;

/**
 * 自定义视图解析(通过配置实现多视图整合,如jsp,velocity,freemarker,pdf,excel...)
 * @author huligong
 *
 */
public class JeeDevViewResolver implements ViewResolver  {
    
    private static Log logger = LogFactory.getLog(JeeDevViewResolver.class);

    public View resolveViewName(String viewName, Locale locale) throws Exception {
       for(Map.Entry<Set<String>, ViewResolver> map : viewResolverMap.entrySet()){
           Set<String> suffixs = map.getKey();
           for(String suffix : suffixs){
               if (viewName.endsWith(suffix)){
                   ViewResolver viewResolver = map.getValue();
                   if(null != viewResolver){
                       if (logger.isDebugEnabled()) {
                            logger.debug("found viewResolver '" + viewResolver + "' for viewName '" + viewName+ "'");
                        }
                       return viewResolver.resolveViewName(viewName, locale);
                   }
               }
           }
       }
       
       if(defaultViewResolver != null){
           return defaultViewResolver.resolveViewName(viewName, locale);
       }
       // to allow for ViewResolver chaining
       return null;
    }
    
    
    private Map<Set<String>,ViewResolver> viewResolverMap = new HashMap<Set<String>,ViewResolver>();
    
    private ViewResolver defaultViewResolver = null;

    public Map<Set<String>, ViewResolver> getViewResolverMap() {
        return viewResolverMap;
    }

    public void setViewResolverMap(Map<Set<String>, ViewResolver> viewResolverMap) {
        this.viewResolverMap = viewResolverMap;
    }

    public ViewResolver getDefaultViewResolver() {
        return defaultViewResolver;
    }

    public void setDefaultViewResolver(ViewResolver defaultViewResolver) {
        this.defaultViewResolver = defaultViewResolver;
    }
}
复制代码

在自定义视图解析器(其实是视图中转器)中,通过对视图文件的后缀判断(而不是请求地址的后缀)而返回给不同的视图解析器处理。

 

二.视图映射配置dispather-servlet.xml

 

复制代码
<bean id="viewResolver" class="com.jeedev.common.web.springmvc.view.JeeDevViewResolver">
        <property name="defaultViewResolver" ref="beanNameViewResolver"/>
        <property name="viewResolverMap">
            <map>
                <entry>
                    <key>
                        <set>
                            <value>.jsp</value>
                        </set>
                    </key>
                    <ref bean="jspViewResolver"/>
                </entry>
                <entry>
                    <key>
                        <set>
                            <value>.vm</value>
                            <value>.htm</value>
                        </set>
                    </key>
                    <ref bean="velocityViewResolver"/>
                </entry>
                <entry>
                    <key><value>.ftl</value></key>
                    <ref bean="freeMarkerViewResolver"/>
                </entry>
            </map>
        </property>
    </bean>

    
    <bean id="beanNameViewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
    
    <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>
    
    <!--  Velocity ViewResolver Configuration -->
    <bean id="velocityViewResolver" class = "org.springframework.web.servlet.view.velocity.VelocityViewResolver">
         <property name="order" value="0" />
         <property name="contentType" value="text/html;charset=UTF-8" />
         <property name="requestContextAttribute" value="req"/>
    </bean>

    <!-- Velocity Configuration -->     
    <bean id="velocityConfig" class = "org.springframework.web.servlet.view.velocity.VelocityConfigurer">
         <property name="configLocation" value="/WEB-INF/velocity.properties"/>
         <property name="resourceLoaderPath" value="/" />
    </bean>
    
    <!--  FreeMarker ViewResolver Configuration -->
    <bean id="freeMarkerViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">  
        <property name="order" value="0" />
        <property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"/>  
    </bean> 
    
    
    <!-- FreeMarker Configuration -->     
    <bean id="freemarkerConfig"  class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">  
       <property name="configLocation" value="/WEB-INF/freemarker.properties"/>
        <property name="templateLoaderPath" value="/WEB-INF/ftl/"/>  
         <property name="freemarkerVariables">
             <map>
                <entry key="xml_escape" value-ref="fmXmlEscape"/>
            </map>
         </property>
    </bean>   
    
    <bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape"/>
复制代码

这里我配置成所有返回.jsp的视图模板请求都转到JSP视图解析器jspViewResolver中去处理,返回.htm,.vm视图模板请求都转到velocity视图解析器中去处理。

 

三.控制器代码示例

 

复制代码
package com.jeedev.demo.view;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * 多视图解析器支持示例
 * @author huligong
 *
 */
@Controller
@RequestMapping(value = "/demo")
public class JeeDevViewResolverTestController {
    private static Log logger = LogFactory.getLog(JeeDevViewResolverTestController.class);
    
    @RequestMapping(value = "/test1")
    public String test1(HttpServletRequest request, ModelMap map) {
        logger.info("使用JSP视图解析器");
        map.put("name", "hello world");
        return "jspTest.jsp";
    }
    
    @RequestMapping(value = "/test2")
    public String test2(HttpServletRequest request, ModelMap map) {
        logger.info("使用Freemarker视图解析器");
        map.put("name", "hello world");
        return "hello.ftl";
    }
    
    @RequestMapping(value = "/test3")
    public String test3(HttpServletRequest request, ModelMap map) {
        logger.info("使用Velocity视图解析器");
        map.put("name", "hello world");
        return "/html/demo.htm";
    }
}
复制代码

 

四.测试请求

我在web.xml里给DispatcherServlet添加了/view/*,所以,只要在请求前加上/view就可以了。

http://localhost:8080/view/demo/test1

http://localhost:8080/view/demo/test2

http://localhost:8080/view/demo/test3

皆验证通过。


第二种方式

说明一下目录结构
 
Spring配置文件

<? xml version="1.0" encoding="UTF-8" ?>
< beans  xmlns ="http://www.springframework.org/schema/beans"
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p
="http://www.springframework.org/schema/p"
    xmlns:context
="http://www.springframework.org/schema/context"
    xsi:schemaLocation
="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd"
>
    
< context:component-scan
        
base-package ="com.spring.action"   />
    
<!--   
        org.springframework.web.servlet.view.ResourceBundleViewResolver
        用于多个视图集成时,ResourceBundleViewResolver是通过解析资源文件来解析请求输出文件的。
        <property name="basename" value="views"></property>,即表示在/WEB-INF/classes路径下有一个
        views.properties文件,本例中views.properties的内容为
        welcome.(class)=org.springframework.web.servlet.view.velocity.VelocityView
        welcome.url=welcome.vm
        freemarker.(class)=org.springframework.web.servlet.view.freemarker.FreeMarkerView
        freemarker.url=freemarker.ftl
    
-->
    
< bean  class ="org.springframework.web.servlet.view.ResourceBundleViewResolver" >
        
< property  name ="basename"  value ="views" ></ property >
        
<!--  
            <property name="order" value="0"></property>
        
-->
    
</ bean >
    
    
<!--  jsp视图解析器  -->
    
< bean  id ="jspViewResolver"  class ="org.springframework.web.servlet.view.InternalResourceViewResolver" >
        
< property  name ="viewClass"  value ="org.springframework.web.servlet.view.JstlView" />
        
< property  name ="prefix"  value ="/" />
        
< property  name ="suffix"  value =".jsp" />
    
</ bean >         
    
    
<!--  velocity视图解析器  -->
    
< bean  id ="velocityViewResolver"  class ="org.springframework.web.servlet.view.velocity.VelocityViewResolver" >
        
< property  name ="cache"  value ="true" />
        
< property  name ="prefix"  value ="/" />
        
< property  name ="suffix"  value =".vm" />
    
</ bean >
    
    
<!--  velocity环境配置  -->
    
< bean  id ="velocityConfig"  class ="org.springframework.web.servlet.view.velocity.VelocityConfigurer" >
        
<!--  velocity配置文件路径  -->
        
< property  name ="configLocation"  value ="/WEB-INF/velocity.properties" />
        
<!--  velocity模板路径  -->
        
< property  name ="resourceLoaderPath"  value ="/WEB-INF/velocity/" />
    
</ bean >
    
    
<!--  FreeMarker环境配置  -->
    
< bean  id ="freemarkerConfig"  class ="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer" >
        
<!--  freemarker模板位置  -->
        
< property  name ="templateLoaderPath"  value ="/WEB-INF/freemarker/" />
    
</ bean >
    
    
<!--  FreeMarker视图解析  -->
    
< bean  id ="freeMarkerViewResolver"  class ="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver" >
        
< property  name ="cache"  value ="true" />
        
< property  name ="prefix"  value ="/" />
        
< property  name ="suffix"  value =".ftl" />
    
</ bean >
</ beans >
views.properties
#welcome为modelAndView.setViewName( " welcome " ) ; 中的welcome   .(class)固定写法
welcome.(class) = org.springframework.web.servlet.view.velocity.VelocityView
#welcome.url 路径 welcome.vm模板名称
welcome.url
= welcome.vm

#freemarker为modelAndView.setViewName(
" freemarker " ) ; 中的freemarker   .(class)固定写法
freemarker.(class) = org.springframework.web.servlet.view.freemarker.FreeMarkerView
#freemarker.url 路径 freemarker.ftl模板名称
freemarker.url
= freemarker.ftl

第三种方式:自适应匹配,不存在则找下一种,使用orders

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"  
  4.     xmlns:mvc="http://www.springframework.org/schema/mvc"  
  5.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  
  6.         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd  
  7.         http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">  
  8.   
  9.   
  10.     <context:component-scan base-package="test.**.controller"  
  11.         use-default-filters="false">  
  12.         <context:include-filter type="annotation"  
  13.             expression="org.springframework.stereotype.Controller" />  
  14.     </context:component-scan>  
  15.   
  16.     <mvc:default-servlet-handler />  
  17.     <mvc:resources location="/resources/" mapping="/resources/**" />  
  18.   
  19.     <mvc:annotation-driven>  
  20.         <!-- <mvc:argument-resolvers> <bean class="org.springframework.data.web.PagedResourcesAssemblerArgumentResolver"   
  21.             /> </mvc:argument-resolvers> -->  
  22.         <mvc:message-converters>  
  23.             <bean class="org.springframework.http.converter.StringHttpMessageConverter">  
  24.                 <property name="supportedMediaTypes">  
  25.                     <list>  
  26.                         <value>text/plain;charset=UTF-8</value>  
  27.                         <value>text/html;charset=UTF-8</value>  
  28.                     </list>  
  29.                 </property>  
  30.             </bean>  
  31.             <bean  
  32.                 class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">  
  33.                 <property name="supportedMediaTypes">  
  34.                     <list>  
  35.                         <value>text/html;charset=UTF-8</value>  
  36.                         <value>application/json;charset=UTF-8</value>  
  37.                     </list>  
  38.                 </property>  
  39.             </bean>  
  40.         </mvc:message-converters>  
  41.     </mvc:annotation-driven>  
  42.   
  43.     <bean id="multipartResolver"  
  44.         class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />  
  45.   
  46.   
  47.     <!-- FreeMarker视图解析 如返回student。。在这里配置后缀名ftl和视图解析器。。-->  
  48.     <bean id="freemarkerConfig"  
  49.         class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">  
  50.         <property name="templateLoaderPath">    
  51.             <value>/WEB-INF/ftl/</value>    
  52.         </property>    
  53.         <property name="defaultEncoding" value="UTF-8" />  
  54.         <property name="freemarkerVariables">  
  55.             <map>  
  56.                 <entry key="xml_escape" value-ref="fmXmlEscape" />  
  57.             </map>  
  58.         </property>  
  59.   
  60.         <property name="freemarkerSettings">  
  61.             <props>  
  62.                 <!--<prop key="template_update_delay">3600</prop> -->  
  63.                 <prop key="tag_syntax">auto_detect</prop>  
  64.                 <!-- 设置标签类型 两种:[] 和 <> 。[] 这种标记解析要快些 -->  
  65.                 <prop key="default_encoding">UTF-8</prop>  
  66.                 <prop key="output_encoding">UTF-8</prop>  
  67.                 <prop key="locale">zh_CN</prop>  
  68.                 <prop key="date_format">yyyy-MM-dd</prop>  
  69.                 <prop key="time_format">HH:mm:ss</prop>  
  70.                 <prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop>  
  71.                 <prop key="number_format">#.##</prop>  
  72.                 <!-- 设置数字格式 以免出现 000.00 -->  
  73.                 <prop key="classic_compatible">true</prop>  
  74.                 <!-- 可以满足一般需要。默认情况变量为null则替换为空字符串,如果需要自定义,写上${empty!"EmptyValue of fbysss"}的形式即可 -->  
  75.                 <prop key="template_exception_handler">html_debug</prop>  
  76.                 <!-- ignore,debug,html_debug,rethrow -->  
  77.             </props>  
  78.         </property>  
  79.     </bean>  
  80.   
  81.     <bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape" />  
  82.   
  83.       
  84.     <bean id="viewResolver"  
  85.         class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">  
  86.         <property name="viewClass"  
  87.             value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"></property>  
  88.         <property name="suffix" value=".ftl" />  
  89.         <property name="contentType" value="text/html;charset=utf-8" />  
  90.         <property name="exposeRequestAttributes" value="true" />  
  91.         <property name="exposeSessionAttributes" value="true" />  
  92.         <property name="exposeSpringMacroHelpers" value="true" />  
  93.         <property name="order" value="0" />  
  94.     </bean>  
  95.       
  96.     <!-- -->   
  97.       
  98.     <!-- Velocity  -->  
  99.     <bean id="velocityConfig"  
  100.         class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">  
  101.         <property name="configLocation" value="/WEB-INF/classes/velocity.properties" />  
  102.         <property name="resourceLoaderPath" value="/WEB-INF/vm/" />  
  103.     </bean>  
  104.       
  105.     <bean id="velocityViewResolver"  
  106.         class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">  
  107.         <property name="order" value="1" />  
  108.         <property name="contentType" value="text/html;charset=UTF-8" />  
  109.         <property name="requestContextAttribute" value="req" />  
  110.         <property name="suffix" value=".vm"/>  
  111.     </bean>  
  112.     <!-- -->   
  113.       
  114.     <bean id="beanNameViewResolver"  
  115.         class="org.springframework.web.servlet.view.BeanNameViewResolver">  
  116.         <property name="order" value="6"/>  
  117.     </bean>  
  118.       
  119.     <bean id="JSPviewResolver"  
  120.         class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
  121.         <property name="viewClass"  
  122.             value="org.springframework.web.servlet.view.JstlView" />  
  123.         <property name="prefix" value="/WEB-INF/jsp/" />  
  124.         <property name="suffix" value=".jsp" />  
  125.         <property name="order" value="10"/>  
  126.     </bean>  
  127.   
  128.     <!-- <bean id="viewResolver"  
  129.         class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">  
  130.         <property name="defaultContentType" value="application/json" />  
  131.         <property name="mediaTypes">  
  132.             <map>  
  133.                 <entry key="html" value="text/html" />  
  134.                 <entry key="json" value="application/json" />  
  135.                 <entry key="xml" value="application/xml" />  
  136.                 <entry key="excel" value="application/excel" />  
  137.                 <entry key="pdf" value="application/pdf" />  
  138.             </map>  
  139.         </property>  
  140.         <property name="viewResolvers">  
  141.             <list>  
  142.                 <bean  
  143.                     class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">  
  144.                     <property name="viewClass"  
  145.                         value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"></property>  
  146.                     <property name="suffix" value=".ftl" />  
  147.                     <property name="contentType" value="text/html;charset=utf-8" />  
  148.                     <property name="exposeRequestAttributes" value="true" />  
  149.                     <property name="exposeSessionAttributes" value="true" />  
  150.                     <property name="exposeSpringMacroHelpers" value="true" />  
  151.                 </bean>  
  152.                 <bean  
  153.                     class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
  154.                     <property name="viewClass"  
  155.                         value="org.springframework.web.servlet.view.JstlView" />  
  156.                     <property name="prefix" value="/WEB-INF/jsp/" />  
  157.                     <property name="suffix" value=".jsp" />  
  158.                 </bean>  
  159.                   
  160.             </list>   
  161.         </property>  
  162.         <property name="defaultViews">  
  163.             <list>  
  164.                 <bean  
  165.                     class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">  
  166.                     <property name="prettyPrint" value="true" />  
  167.                     <property name="contentType" value="text/plain" />  
  168.                 </bean>  
  169.             </list>  
  170.         </property>  
  171.     </bean>  
  172.  -->  
  173.     <!--定义异常处理页面 -->  
  174.     <bean id="exceptionResolver"  
  175.         class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">  
  176.         <property name="exceptionMappings">  
  177.             <props>  
  178.                 <prop key="java.lang.Exception">outException</prop>  
  179.             </props>  
  180.         </property>  
  181.     </bean>  
  182.       
  183.   
  184.   
  185.   
  186.   
  187. </beans>  

猜你喜欢

转载自blog.csdn.net/bestone0213/article/details/49335533