SpringMVC同时支持多视图(JSP,Velocity,Freemarker等)的一种思路实现

[导读]在基于SpringMVC的项目中有时需要同时使用多种视图格式,如jsp,velocity及freemarker等,通过不同的请求路径配置规则,映射到不同的视图文件。下面我提供一种思路,通过视图模板文件后缀名的方式来进行处理。例如:@RequestMapping(value = "/hello") public String jspTest(HttpServletRequest request, M...

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

1
2
3
4
@RequestMapping(value = "/hello"
public String jspTest(HttpServletRequest request, ModelMap map) { 
    return "demo.jsp"
}

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

下面描述下详细思路:

一.自定义视图解析器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<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视图解析器中去处理。

三.控制器代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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

皆验证通过。

posted @ 2014-01-13 10:23  qsa  阅读(350)  评论(0编辑  收藏  举报