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

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