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
皆验证通过。