[导读]在基于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
皆验证通过。