SpringMVC和Freemarker整合,帶自定義標簽的使用方法。
【參考來源:http://www.360doc.com/content/14/1225/14/1007797_435663342.shtml】
SpringMVC現在是比較熱門的一種框架了,使用起來感覺還是很不錯的,現在我分享一下集體的配置和使用,希望對學習SpringMVC的朋友有用。
一、首先我們做准備工作,下載Spring包,下載Freemarker包。
二、配置web.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
71
72
|
<
context-param
>
<
param-name
>contextConfigLocation</
param-name
>
<
param-value
>classpath*:/applicationContext*.xml</
param-value
>
</
context-param
>
<
filter
>
<
filter-name
>encoding</
filter-name
>
<
filter-class
>
org.springframework.web.filter.CharacterEncodingFilter
</
filter-class
>
<
init-param
>
<
param-name
>encoding</
param-name
>
<
param-value
>UTF-8</
param-value
>
</
init-param
>
<
init-param
>
<
param-name
>forceEncoding</
param-name
>
<
param-value
>true</
param-value
>
</
init-param
>
</
filter
>
<
filter-mapping
>
<
filter-name
>encoding</
filter-name
>
<
url-pattern
>/*</
url-pattern
>
</
filter-mapping
>
<
listener
>
<
listener-class
>
org.springframework.web.context.ContextLoaderListener
</
listener-class
>
</
listener
>
<!-- Spring 的servlet -->
<
servlet
>
<
servlet-name
>spring</
servlet-name
>
<
servlet-class
>
org.springframework.web.servlet.DispatcherServlet
</
servlet-class
>
<
init-param
>
<
param-name
>contextConfigLocation</
param-name
>
<
param-value
>classpath:spring-servlet.xml</
param-value
>
</
init-param
>
<
load-on-startup
>1</
load-on-startup
>
</
servlet
>
<
servlet-mapping
>
<
servlet-name
>spring</
servlet-name
>
<
url-pattern
>/</
url-pattern
>
</
servlet-mapping
>
<
servlet-mapping
>
<
servlet-name
>default</
servlet-name
>
<
url-pattern
>*.jpg</
url-pattern
>
</
servlet-mapping
>
<
servlet-mapping
>
<
servlet-name
>default</
servlet-name
>
<
url-pattern
>*.png</
url-pattern
>
</
servlet-mapping
>
<
servlet-mapping
>
<
servlet-name
>default</
servlet-name
>
<
url-pattern
>*.js</
url-pattern
>
</
servlet-mapping
>
<
servlet-mapping
>
<
servlet-name
>default</
servlet-name
>
<
url-pattern
>*.css</
url-pattern
>
</
servlet-mapping
>
<
welcome-file-list
>
<
welcome-file
>index.html</
welcome-file
>
</
welcome-file-list
>
<
error-page
>
<
error-code
>404</
error-code
>
<
location
>/404.jsp</
location
>
</
error-page
>
<
error-page
>
<
error-code
>500</
error-code
>
<
location
>/500.jsp</
location
>
</
error-page
>
|
三、接下來配置applicationContext.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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<
beans
xmlns
=
"http://www.springframework.org/schema/beans"
xmlns:aop
=
"http://www.springframework.org/schema/aop"
xmlns:context
=
"http://www.springframework.org/schema/context"
xmlns:p
=
"http://www.springframework.org/schema/p"
xmlns:tx
=
"http://www.springframework.org/schema/tx"
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:cache
=
"http://www.springframework.org/schema/cache"
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
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.1.xsd
"
default-lazy-init
=
"true"
>
<
description
>Spring數據庫及事務配置</
description
>
<
context:component-scan
base-package
=
"com.mynote.*,com.base.*"
>
<
context:exclude-filter
type
=
"annotation"
expression
=
"org.springframework.stereotype.Controller"
/>
</
context:component-scan
>
<
context:property-placeholder
location
=
"classpath:/jdbc.properties"
/>
<!-- 數據庫連接 -->
<
bean
id
=
"dataSource"
class
=
"org.logicalcobwebs.proxool.ProxoolDataSource"
>
<
property
name
=
"alias"
>
<
value
>proxoolds</
value
>
</
property
>
<
property
name
=
"driver"
>
<
value
>${datasource.driverClassName}</
value
>
</
property
>
<
property
name
=
"driverUrl"
>
<
value
>${datasource.url}</
value
>
</
property
>
<
property
name
=
"user"
>
<
value
>${datasource.username}</
value
>
</
property
>
<
property
name
=
"password"
>
<
value
>${datasource.password}</
value
>
</
property
>
<
property
name
=
"houseKeepingSleepTime"
>
<
value
>${datasource.houseKeepingSleepTime}</
value
>
</
property
>
<
property
name
=
"maximumConnectionCount"
>
<
value
>${datasource.maximumConnectionCount}</
value
>
</
property
>
<
property
name
=
"minimumConnectionCount"
>
<
value
>${datasource.minimumConnectionCount}</
value
>
</
property
>
<
property
name
=
"prototypeCount"
>
<
value
>${datasource.prototypeCount}</
value
>
</
property
>
<
property
name
=
"maximumActiveTime"
value
=
"1800000"
/>
<
property
name
=
"simultaneousBuildThrottle"
value
=
"100"
/>
</
bean
>
<
bean
id
=
"jdbcTemplate"
class
=
"org.springframework.jdbc.core.JdbcTemplate"
>
<
property
name
=
"dataSource"
ref
=
"dataSource"
/>
</
bean
>
<
bean
id
=
"simpleJdbcInsert"
class
=
"org.springframework.jdbc.core.simple.SimpleJdbcInsert"
>
<
constructor-arg
ref
=
"dataSource"
/>
</
bean
>
<!-- 事務管理 -->
<
bean
id
=
"transactionManager"
class
=
"org.springframework.jdbc.datasource.DataSourceTransactionManager"
>
<
property
name
=
"dataSource"
ref
=
"dataSource"
/>
</
bean
>
<
tx:annotation-driven
transaction-manager
=
"transactionManager"
/>
<
bean
id
=
"ehCacheManager"
class
=
"org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
>
<
property
name
=
"shared"
value
=
"true"
/>
</
bean
>
<
bean
id
=
"ehcache"
factory-bean
=
"ehCacheManager"
factory-method
=
"getEhcache"
>
<
constructor-arg
value
=
""
/>
</
bean
>
<
cache:annotation-driven
cache-manager
=
"springEhCacheManager"
/>
<
bean
id
=
"springEhCacheManager"
class
=
"com.base.modules.utils.AutoCreatedEhCacheCacheManager"
>
<
property
name
=
"cacheManager"
ref
=
"ehCacheManager"
/>
</
bean
>
<!-- 定期執行的業務類
<bean id="jdkExecutorJob" class="com.shst.base.bdss.bdssTask" lazy-init="false">
<property name="period" value="180" />
<property name="initialDelay" value="10" />
<property name="shutdownTimeout" value="120" />
</bean>
-->
</
beans
>
|
四、接下來寫spring-servlet.xml配置好jsp和Freemarker的自動切換,只要你的請求指定了跳轉,那么就會先找對應的Freemarker文件然后會找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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
|
<?
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"
xmlns:mvc
=
"http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<
mvc:annotation-driven
/>
<!-- 將無法mapping到Controller的path交給default servlet handler處理 -->
<
mvc:default-servlet-handler
/>
<
context:component-scan
base-package
=
"com.mynote.*"
use-default-filters
=
"false"
>
<
context:include-filter
type
=
"annotation"
expression
=
"org.springframework.stereotype.Controller"
/>
<!--
shiro方法攔截需求
<context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice" />
-->
</
context:component-scan
>
<
mvc:interceptors
>
<!-- 多個攔截器,順序執行 -->
<
mvc:interceptor
>
<
mvc:mapping
path
=
"/**"
/>
<!-- 如果不配置或/*,將攔截所有的Controller -->
<
bean
class
=
"com.base.modules.intercepter.SecurityIntercepter"
></
bean
>
</
mvc:interceptor
>
</
mvc:interceptors
>
<
bean
class
=
"org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver"
p:prefix
=
"/"
p:suffix
=
".ftl"
>
<
property
name
=
"cache"
value
=
"false"
/>
<
property
name
=
"viewClass"
value
=
"org.springframework.web.servlet.view.freemarker.FreeMarkerView"
/>
<
property
name
=
"contentType"
value
=
"text/html;charset=UTF-8"
></
property
>
<
property
name
=
"exposeRequestAttributes"
value
=
"true"
/>
<
property
name
=
"exposeSessionAttributes"
value
=
"true"
/>
<
property
name
=
"exposeSpringMacroHelpers"
value
=
"true"
/>
<
property
name
=
"requestContextAttribute"
value
=
"base"
></
property
>
<
property
name
=
"order"
value
=
"0"
></
property
>
</
bean
>
<
bean
id
=
"multipartResolver"
class
=
"org.springframework.web.multipart.commons.CommonsMultipartResolver"
p:defaultEncoding
=
"UTF-8"
/>
<
bean
id
=
"IndexContentListTag"
class
=
"com.mynote.tag.IndexContentListTag"
>
</
bean
>
<
bean
id
=
"BKIndexContentListTag"
class
=
"com.mynote.tag.BKIndexContentListTag"
>
</
bean
>
<
bean
id
=
"contentTag"
class
=
"com.mynote.tag.ContentTag"
></
bean
>
<
bean
id
=
"HotBlogContentTag"
class
=
"com.mynote.tag.HotBlogContentTag"
>
</
bean
>
<
bean
id
=
"freemarkerConfig"
class
=
"org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"
>
<
property
name
=
"templateLoaderPath"
value
=
"/templates/"
/>
<
property
name
=
"defaultEncoding"
value
=
"UTF-8"
/>
<
property
name
=
"freemarkerVariables"
>
<
map
>
<
entry
key
=
"indexContent"
value-ref
=
"IndexContentListTag"
>
</
entry
>
<
entry
key
=
"bkContent"
value-ref
=
"BKIndexContentListTag"
>
</
entry
>
<
entry
key
=
"blogContent"
value-ref
=
"contentTag"
></
entry
>
<
entry
key
=
"hotContent"
value-ref
=
"HotBlogContentTag"
></
entry
>
</
map
>
</
property
>
<
property
name
=
"freemarkerSettings"
>
<
props
>
<
prop
key
=
"tag_syntax"
>auto_detect</
prop
>
<
prop
key
=
"template_update_delay"
>5</
prop
>
<
prop
key
=
"defaultEncoding"
>UTF-8</
prop
>
<
prop
key
=
"url_escaping_charset"
>UTF-8</
prop
>
<
prop
key
=
"locale"
>zh_CN</
prop
>
<
prop
key
=
"boolean_format"
>true,false</
prop
>
<
prop
key
=
"datetime_format"
>yyyy-MM-dd HH:mm:ss</
prop
>
<
prop
key
=
"date_format"
>yyyy-MM-dd</
prop
>
<
prop
key
=
"time_format"
>HH:mm:ss</
prop
>
<
prop
key
=
"number_format"
>0.######</
prop
>
<
prop
key
=
"whitespace_stripping"
>true</
prop
>
<!--空值處理<prop key="classic_compatible">true</prop>-->
<!-- <prop key="auto_import">/ftl/tags/index.ftl as p,/ftl/spring.ftl as s</prop>-->
</
props
>
</
property
>
</
bean
>
<
bean
class
=
"org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"
/>
<
bean
id
=
"viewResolverCommon"
class
=
"org.springframework.web.servlet.view.InternalResourceViewResolver"
>
<
property
name
=
"viewClass"
value
=
"org.springframework.web.servlet.view.JstlView"
/>
<
property
name
=
"order"
value
=
"1"
></
property
>
<
property
name
=
"prefix"
value
=
"/WEB-INF/"
/>
<
property
name
=
"suffix"
value
=
".jsp"
></
property
>
</
bean
>
<
bean
class
=
"org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"
>
<
property
name
=
"messageConverters"
>
<
list
>
<!-- 解析json請求數據,將json轉換為java對象-->
<
bean
class
=
"org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"
/>
<!-- 解析xml請求數據,將xml轉換為java對象-->
<
bean
class
=
"org.springframework.http.converter.xml.MarshallingHttpMessageConverter"
>
<
constructor-arg
>
<
bean
class
=
"org.springframework.oxm.xstream.XStreamMarshaller"
>
<
property
name
=
"streamDriver"
>
<
bean
class
=
"com.thoughtworks.xstream.io.xml.DomDriver"
/>
</
property
>
<
property
name
=
"autodetectAnnotations"
>
<
value
>true</
value
>
</
property
>
<!--可以與xml互換的對象,需要使用XStream的注解,注解的使用方法請參XStream官網-->
<!--
<property name="annotatedClasses">
<list>
<value>com.xxx.XxxxDTO</value>
</list>
</property>
-->
</
bean
>
</
constructor-arg
>
</
bean
>
<
bean
class
=
"org.springframework.http.converter.FormHttpMessageConverter"
/>
<
bean
class
=
"org.springframework.http.converter.BufferedImageHttpMessageConverter"
/>
<
bean
class
=
"org.springframework.http.converter.ByteArrayHttpMessageConverter"
/>
<
bean
class
=
"org.springframework.http.converter.StringHttpMessageConverter"
/>
<!--
<bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/>
-->
<!--可以增加其他數據類型,請參考spring的API-->
</
list
>
</
property
>
</
bean
>
<
bean
id
=
"fmXmlEscape"
class
=
"freemarker.template.utility.XmlEscape"
/>
<
bean
class
=
"org.springframework.web.servlet.view.ContentNegotiatingViewResolver"
>
<
property
name
=
"ignoreAcceptHeader"
value
=
"true"
/>
<
property
name
=
"defaultContentType"
value
=
"text/html"
/>
<!-- 擴展名至mimeType的映射,即 /user.json => application/json -->
<
property
name
=
"mediaTypes"
>
<
map
>
<
entry
key
=
"html"
value
=
"text/html"
/>
<
entry
key
=
"json"
value
=
"application/json"
/>
<
entry
key
=
"xml"
value
=
"application/xml"
/>
</
map
>
</
property
>
<!-- 用於開啟 /userinfo/123?format=json 的支持 -->
<
property
name
=
"favorParameter"
value
=
"false"
/>
<
property
name
=
"viewResolvers"
>
<
list
>
<
bean
class
=
"org.springframework.web.servlet.view.BeanNameViewResolver"
/>
</
list
>
</
property
>
<
property
name
=
"defaultViews"
>
<
list
>
<!-- for application/json -->
<
bean
class
=
"org.springframework.web.servlet.view.json.MappingJacksonJsonView"
/>
<!-- for application/xml -->
<
bean
class
=
"org.springframework.web.servlet.view.xml.MarshallingView"
>
<
property
name
=
"marshaller"
>
<
bean
class
=
"org.springframework.oxm.xstream.XStreamMarshaller"
/>
</
property
>
</
bean
>
</
list
>
</
property
>
</
bean
>
<
bean
id
=
"localeResolver"
class
=
"org.springframework.web.servlet.i18n.CookieLocaleResolver"
>
<
property
name
=
"cookieName"
value
=
"clientlanguage"
/>
<
property
name
=
"cookieMaxAge"
value
=
"-1"
/>
</
bean
>
<!--
<bean
class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor">
<property name="proxyTargetClass" value="true" />
</bean>
<bean
class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"></property>
</bean>
-->
<
bean
class
=
"org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"
>
<
property
name
=
"exceptionMappings"
>
<
props
>
<
prop
key
=
"java.lang.Throwable"
>500</
prop
>
</
props
>
</
property
>
<
property
name
=
"warnLogCategory"
value
=
"WARN"
></
property
>
<
property
name
=
"defaultErrorView"
value
=
"500"
></
property
>
<
property
name
=
"defaultStatusCode"
value
=
"500"
></
property
>
<
property
name
=
"statusCodes"
>
<
props
>
<
prop
key
=
"404"
>404</
prop
>
<
prop
key
=
"500"
>500</
prop
>
</
props
>
</
property
>
</
bean
>
</
beans
>
|
五、接下來就開始寫java類了,我們將使用注解來實現功能
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
|
@Controller
@RequestMapping
public
class
ContentController {
@Autowired
private
TemplatesService templatesService;
@Autowired
private
BlogContentService contentService;
@Autowired
private
BlogInfoService blogInfoService;
@RequestMapping
(
"{username}/{contentId}.html"
)
public
String content(HttpServletRequest request,
@PathVariable
String username,
@PathVariable
String contentId) {
// 獲得模版路徑執行跳轉
String path=templatesService.getTemplatesPath(username);
BlogInfo info = blogInfoService.findBlogInfoByUserName(username);
if
(info==
null
){
info =
new
BlogInfo();
info.setName(
"OSblog"
);
info.setDes(
"我的博客我做主"
);
info.setNickname(
"Osblog博客"
);
}
request.setAttribute(
"bloginfo"
, info);
contentService.updateclicks(contentId);
request.setAttribute(
"bloguser"
, username);
BlogContent content=contentService.getEntityById(contentId);
request.setAttribute(
"content"
, content);
return
path+
"/content"
;
}
}
|
這是一個控制器,和Struts中Action是一樣的,上面的方法是動態接受請求的方法,比如請求是http://localhost:8080/osblog/12.html,在控制器中取到的username=osblog,contentid=12,是不是很智能啊。
剩下的數據層和業務層寫法就沒有什么可寫的了,注解的方式也和普通注解一樣。在配置文件中寫到了:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<
bean
class
=
"org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver"
p:prefix
=
"/"
p:suffix
=
".ftl"
>
<
property
name
=
"cache"
value
=
"false"
/>
<
property
name
=
"viewClass"
value
=
"org.springframework.web.servlet.view.freemarker.FreeMarkerView"
/>
<
property
name
=
"contentType"
value
=
"text/html;charset=UTF-8"
></
property
>
<
property
name
=
"exposeRequestAttributes"
value
=
"true"
/>
<
property
name
=
"exposeSessionAttributes"
value
=
"true"
/>
<
property
name
=
"exposeSpringMacroHelpers"
value
=
"true"
/>
<
property
name
=
"requestContextAttribute"
value
=
"base"
></
property
>
<
property
name
=
"order"
value
=
"0"
></
property
>
</
bean
>
|
這個就是指明了你調轉的視圖是Freemarker的,同理另一個指明的是jsp按照順序他們會自動選這你要跳轉的視圖。不過在注解是@RequestMapping("sitemap.html")里面的值絕對不能重復的。