二、 struts.xml 配置及例程
1. 配置文件的優先級
在 struts2 中一些配置(比如常量)可以同時在 struts-default.xml (只讀性), strtus-plguin.xml (只讀性), struts.xml , struts.properties 和 web.xml 文件中配置,它們的優先級逐步升高,即是說后面的配置會覆蓋掉前面相同的配置。
2. 配置形式
下面以對 struts.i18n.encoding=UTF-8 的配置為例進行說明:
在 struts.xml 配置形式如下:
??? < constant name = "struts.i18n.encoding" value = "gbk" ></ constant >
在 struts.properties 的配置形式如下:
struts.i18n.encoding=UTF-8
在
web.xml
中配置如下:
<
filter
>
< filter-name > struts2 </ filter-name >
< filter-class > ??? org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
??? </ filter-class >
??? < init-param >
?????? < param-name > struts.i18n.encoding </ param-name >
?????? < param-value > UTF-8 </ param-value >
??? </ init-param >
</
filter
>
說明
:
官方聲稱配置了此常量可以解決中文亂碼問題,但實事上并不能達到目的,在前面的三個項目中,如果我們在表單中輸入中文,其結果是會出現亂碼。解決此問題參看
[
一
.7
的注意
]
。這是
struts2.1.6
中的一
bug,
它的下一版
2.1.8
已解決此問題。
3.package 配置相關
屬性名 |
是否必須 |
說明 |
Name |
是 |
Package 的唯一標識,不允許同名 |
Extends |
否 |
指定要繼承的包 |
Namespace |
否 |
指定名稱空間 |
Abstract |
否 |
聲明包為抽象否 |
下面我們建立 struts2package 項目 來進行 package 相關測試:
?
6. 初識攔截器
攔截器能在 action 被調用之前和被調用之后執行一些 “ 代碼 ” 。 Struts2 框架的大部分核心功能都是通過攔截器來實現的,如防止重復提交、類型轉換、對象封裝、校驗、 文件上傳 、頁面預裝載等等,都是在攔截器的幫助下實現的。每一個攔截器都是獨立裝載的 (pluggable) ,我們可以根據實際的需要為每一個 action 配置它所需要的攔截器。
在
myStruts2
項目
下,重新對配置文件作如下修改:
<
package
name
=
"myFirst"
namespace
=
"/"
extends
=
"struts-default"
>
< interceptors >
< interceptor name = "timer"
????????????? class = "com.opensymphony.xwork2.interceptor.TimerInterceptor" />
???
<
interceptor
name
=
"params"
????????????
??????????
?????????????????????????????????????????????????????????????????????????????
class
=
"com.opensymphony.xwork2.interceptor.ParametersInterceptor"
/>
??? </ interceptors >
?
?????? < action name = "login" class = "com.asm.LoginAction" >
?????????? < interceptor-ref name = "timer" ></ interceptor-ref >
?????????? < interceptor-ref name = "params" ></ interceptor-ref >
?????????? < result name = "loginSuccess" > /success.jsp </ result >
?????????? < result name = "loginFailure" > /failure.jsp </ result >
?????? </ action >
??? </ package >
首先在 package 中定義了兩個攔截器,然后在 login action 中引用了這兩個攔截器,需要說明的是這里使用的攔截器都是系統自帶的攔截器。其實在 extends 所繼承的 struts-default 中就包含了很多攔截器,也包括我們這里所用的攔截器,但如果在此 action 中不使用 params 攔截器,將會報空指針錯,因為 params 攔截器的作用是傳遞表單參數,如果不使用此攔截器就不能在 action 中得到表單參數,所以引用時會報空指針錯。雖然 extends 繼承的 strust-default 自帶有 params 攔截器,但是當我們自己引用了攔截器時,繼承 struts-default 將不會再為我們分配默認的攔截器(有點類似構造器),但是我們仍然可以通過 < interceptor-ref name = "defaultStack" /> 來繼續使用 struts-defalut 的攔截器。 補充 :由于上面的 package 繼承于 struts-default ,而我們這里所用到的 timer 和 params 都是在 struts-defalut 中定義過,所以即使我們在 < interceptors > 中沒有定義過這兩個攔截器,也可以直接在 action 中引用。
使用 </ interceptor-stack > 組合多個攔截器 :比如我們想把上面的 params 和 timer 這兩個攔截器組合:
??? < interceptor-stack name = "timer_param" >
????????????? < interceptor-ref name = "timer" />
????????????? < interceptor-ref name = "params" />
??? </ interceptor-stack >
然后再在 action 引用 < interceptor-ref name = "timer_param" /> ”,效果和分別引用兩個是一樣的。其實我們使用 strtus-default 中的 < interceptor-ref name = "defaultStack" /> 也是使用 interceptor-stack 方式。
?
說明:
在上面的配置文件中所用到的
Test1Action
和
Test2Action
這兩個
Action
都只是繼承了
com.opensymphony.xwork2.ActionSupport
類,而
ActionSupport
默認返回的就是“
success
”
,
所以當點擊上面的鏈接分別轉到了
forward
目錄下的
test1.jsp
和
test2.jsp
。下面重點來看這個
package
元素的
namespace
屬性及
action
的
name
屬性,它們共同定義了
action
所映射到的實質文件。上圖展示了鏈接地址和
action
的對應關系,
所以當我們要想訪問一個
action
所關聯到的
jsp
文件時,應該用
namespace+action
的
name
關于它的內容測試可以參考
struts2package
項目。
補充
:通常情況下,
action
元素的
name
是屬性值是不能出現“
/
”的,所以希望通過
action
中
name
屬性來實現多級映射,需要在
sturts.xml
中增加如下屬性:
?
<
constant
name
=
"struts.enable.SlashesInActionNames"
value
=
"true"
/>
這樣配置后就可以再
action
的
name
元素中使用“
/
”了。比如:
<
package
name
=
"tt3"
extends
=
"struts-default"
>
?????? < action name = "test3/test3" class = "com.asm.Test3Action" >
?????????? < result name = "success" > /forward/test3.jsp </ result >
?????? </ action >
</ package >
然后輸入 < a href = " <%= path %> /test3/test3.action " > test3 </ a >< br > 鏈接地址就可以訪問了
強調 : namespace 默認值“”,即不配置 namespace 屬性。它的意思是:如果 action 不能進行完整路徑匹配,則會來此 namespace 下進行匹配,比如: .../test/test/test.action ,如果參照 namespace 及 action 的 name 不能找到也之完全對應的 action ,它會再到依次追溯到上級目錄中查找,即是說它會以 …/test/test.action 這樣的路徑來對應 namespace 和 action 的 name 進行查找。如果返回到最終的目錄仍找不到,它就會到 namespace = "/" 對應的包下查找名為 test 的 action, 如果仍找不到,它就會去默認的 namespace 下查找名為 test 的 action ,如果找到則執行此 action 。 另外 , namespace 也可以配置成 namespace = "/" 。它代表配置為項目的根。 總結 action 的名稱探索順序:完全對應、逐步追溯到上級目錄查找、 "/" 下查找、默認 namespace 下查找。
為什么要提出
namespace
,主要是避免多人共同開發項目出現名字沖突。如果不使用
namespace
,多個人所寫的
action
中可能出現重名的現象,這樣當項目合并時就會出現沖突。而有了
namespace
可以在項目開發時由項目經理給每一個人分不同的
namespace
,這樣每個開發人員只需要保證自己所寫的
action
不同名即可。
namespace
引發的鏈接問題
:當我們為
action
配置了
namespace
時,訪問此
action
的形式總會是如下形式:
.../webappname/xxx/yyy/ActionName.action
而當此
action
成功執行跳轉到某個
jsp
頁面時,如想在此
jsp
頁面寫鏈接,一定要寫絕對路徑,因為相對路徑是相對
.../webappname/xxx/yyy/
,而如果以后我們修改了
action
的
namespace
時,相對路徑又要變,所以鏈接不能寫成相對路徑。以下介紹絕對路徑的寫法:通常用
myeclipse
開發時建立一個
jsp
文件,默認總會有如下內容:
<%
String path = request.getContextPath();
String basePath = request.getScheme()+ "://" +request.getServerName()+ ":" +request.getServerPort()+path+ "/" ;
%>
我們寫絕對路徑可以參此內容。還可以參
<head>
下的
<
base
href
=
"
<%=
basePath
%>
"
>
來完成絕對路徑的書寫。
4. 分工合作 include: 指定多個配置文件
比如讓
jack
來單獨開發一個
action
,在
jack.xml
中的配置文件為:
<
struts
>
??? < package name = "jack" namespace = "/jack" extends = "struts-default" >
?????? < action name = "test4" class = "com.asm.Test4Action" >
?????????? < result name = "success" > /forward/test4.jsp </ result >
?????? </ action >
??? </ package >
</ struts >
然后在 struts.xml 文件中增加如下內容: < include file = "jack.xml" ></ include > 它實質就是把 jack.xml 中的 <package> 及其內容寫進 struts.xml 中的 < struts > 根元素下。
鏈接: < a href = " <%= path %> /jack/test4.action " > test4 </ a > 這樣便可以訪問到了 forward 目錄下的 test4.jsp 了。
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
