日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

struts2.1.6教程二、struts.xml配置及例程

發(fā)布時間:2023/12/19 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 struts2.1.6教程二、struts.xml配置及例程 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?

1.配置文件的優(yōu)先級

在struts2中一些配置(比如常量)可以同時在struts-default.xml(只讀性),strtus-plguin.xml(只讀性),struts.xml,struts.properties和web.xml文件中配置,它們的優(yōu)先級逐步升高,即是說后面的配置會覆蓋掉前面相同的配置。

?

2.配置形式

下面以對struts.i18n.encoding=UTF-8的配置為例進(jìn)行說明:

在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>

說明:官方聲稱配置了此常量可以解決中文亂碼問題,但實(shí)事上并不能達(dá)到目的,在前面的三個項(xiàng)目中,如果我們在表單中輸入中文,其結(jié)果是會出現(xiàn)亂碼。解決此問題參看[一.7的注意]。這是struts2.1.6中的一bug,它的下一版2.1.8已解決此問題。

?

3.package配置相關(guān)

屬性名

是否必須

說明

Name

Package的唯一標(biāo)識,不允許同名

Extends

指定要繼承的包

Namespace

指定名稱空間

Abstract

聲明包為抽象否

?

?

說明:在上面的配置文件中所用到的Test1Action和Test2Action這兩個Action都只是繼承了com.opensymphony.xwork2.ActionSupport類,而ActionSupport默認(rèn)返回的就是“success”,所以當(dāng)點(diǎn)擊上面的鏈接分別轉(zhuǎn)到了forward目錄下的test1.jsp和test2.jsp。下面重點(diǎn)來看這個package元素的namespace屬性及action的name屬性,它們共同定義了action所映射到的實(shí)質(zhì)文件。上圖展示了鏈接地址和action的對應(yīng)關(guān)系,所以當(dāng)我們要想訪問一個action所關(guān)聯(lián)到的jsp文件時,應(yīng)該用namespace+action的name 關(guān)于它的內(nèi)容測試可以參考struts2package項(xiàng)目。

?

補(bǔ)充:通常情況下,action元素的name是屬性值是不能出現(xiàn)“/”的,所以希望通過action中name屬性來實(shí)現(xiàn)多級映射,需要在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>鏈接地址就可以訪問了

?

強(qiáng)調(diào)namespace默認(rèn)值“”,即不配置namespace屬性。它的意思是:如果action不能進(jìn)行完整路徑匹配,則會來此namespace下進(jìn)行匹配,比如:.../test/test/test.action,如果參照namespace及action的name不能找到也之完全對應(yīng)的action,它會再到依次追溯到上級目錄中查找,即是說它會以…/test/test.action這樣的路徑來對應(yīng)namespace和action的name進(jìn)行查找。如果返回到最終的目錄仍找不到,它就會到namespace="/"對應(yīng)的包下查找名為test的action,如果仍找不到,它就會去默認(rèn)的namespace下查找名為test的action,如果找到則執(zhí)行此action。另外,namespace也可以配置成namespace="/"。它代表配置為項(xiàng)目的根。 總結(jié)action的名稱探索順序:完全對應(yīng)、逐步追溯到上級目錄查找、"/"下查找、默認(rèn)namespace下查找。

?

為什么要提出namespace,主要是避免多人共同開發(fā)項(xiàng)目出現(xiàn)名字沖突。如果不使用namespace,多個人所寫的action中可能出現(xiàn)重名的現(xiàn)象,這樣當(dāng)項(xiàng)目合并時就會出現(xiàn)沖突。而有了namespace可以在項(xiàng)目開發(fā)時由項(xiàng)目經(jīng)理給每一個人分不同的namespace,這樣每個開發(fā)人員只需要保證自己所寫的action不同名即可。

?

namespace引發(fā)的鏈接問題:當(dāng)我們?yōu)閍ction配置了namespace時,訪問此action的形式總會是如下形式:.../webappname/xxx/yyy/ActionName.action 而當(dāng)此action成功執(zhí)行跳轉(zhuǎn)到某個jsp頁面時,如想在此jsp頁面寫鏈接,一定要寫絕對路徑,因?yàn)橄鄬β窂绞窍鄬?../webappname/xxx/yyy/,而如果以后我們修改了action的namespace時,相對路徑又要變,所以鏈接不能寫成相對路徑。 以下介紹

1.絕對路徑的寫法:通常用myeclipse開發(fā)時建立一個jsp文件,默認(rèn)總會有如下內(nèi)容:

<% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %>我們寫絕對路徑可以參此內(nèi)容。還可以參<head>下的<base href="<%=basePath%>"> 來完成絕對路徑的書寫。

?

4.分工合作include:指定多個配置文件

比如讓jack來單獨(dú)開發(fā)一個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)容寫進(jìn)struts.xml中的<struts>根元素下。

?

鏈接:<a href="<%=path %>/jack/test4.action">test4</a> 這樣便可以訪問到了forward目錄下的test4.jsp了。

?

?

5.tomcat認(rèn)證訪問

接上例:namespce的作用除了在前面提到的避免協(xié)同開發(fā)名字沖突外,還為認(rèn)證提供一個條件。比如jack開發(fā)的東西所關(guān)聯(lián)到的頁面需要權(quán)限才能被訪問。由于多為tomcat中的內(nèi)容,下面只列出步驟。
步驟一,tomcat的conf目錄下tomcat-users.xml內(nèi)容如下:

<?xml version='1.0' encoding='utf-8'?> <tomcat-users><role rolename="manager"/><role rolename="admin"/><user username="jack" password="jack" roles="admin,manager"/><user username="tom" password="tom" roles="manager"/> </tomcat-users> 步驟二,在web.xml中增加如下內(nèi)容:
<security-constraint><web-resource-collection><web-resource-name>jack</web-resource-name><url-pattern>/jack/*</url-pattern><http-method>POST</http-method><http-method>GET</http-method></web-resource-collection><auth-constraint><role-name>admin</role-name></auth-constraint></security-constraint><security-role><role-name>admin</role-name></security-role><login-config><auth-method>BASIC</auth-method><realm-name>input authentication message</realm-name></login-config>

這樣配置完成后,當(dāng)我們訪問.../jack中的任何內(nèi)容都會要求輸入密碼認(rèn)證信息,認(rèn)證時輸入tomcat-users.xml配置的admin權(quán)限的用戶名和密碼即可訪問(這里就只有jack用戶名可以訪問)

?

6.初識攔截器

攔截器能在action被調(diào)用之前和被調(diào)用之后執(zhí)行一些“代碼”。Struts2框架的大部分核心功能都是通過攔截器來實(shí)現(xiàn)的,如防止重復(fù)提交、類型轉(zhuǎn)換、對象封裝、校驗(yàn)、文件上傳、頁面預(yù)裝載等等,都是在攔截器的幫助下實(shí)現(xiàn)的。每一個攔截器都是獨(dú)立裝載的(pluggable),我們可以根據(jù)實(shí)際的需要為每一個action配置它所需要的攔截器。

myStruts2項(xiàng)目下,重新對配置文件作如下修改:

<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中引用了這兩個攔截器,需要說明的是這里使用的攔截器都是系統(tǒng)自帶的攔截器。其實(shí)在extends所繼承的struts-default中就包含了很多攔截器,也包括我們這里所用的攔截器,但如果在此action中不使用params攔截器,將會報空指針錯,因?yàn)閜arams攔截器的作用是傳遞表單參數(shù),如果不使用此攔截器就不能在action中得到表單參數(shù),所以引用時會報空指針錯。雖然extends繼承的strust-default自帶有params攔截器,但是當(dāng)我們自己引用了攔截器時,繼承struts-default將不會再為我們分配默認(rèn)的攔截器(有點(diǎn)類似構(gòu)造器),但是我們?nèi)匀豢梢酝ㄟ^<interceptor-ref name="defaultStack"/>來繼續(xù)使用struts-defalut的攔截器。補(bǔ)充:由于上面的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"/>”,效果和分別引用兩個是一樣的。其實(shí)我們使用strtus-default中的<interceptor-ref name="defaultStack"/>也是使用interceptor-stack方式。

?

7.Action中的method屬性

在struts1.x中我們知道通過繼承DispatchAction可以實(shí)現(xiàn)把多個Action進(jìn)行統(tǒng)一操作,在struts2中實(shí)現(xiàn)action的統(tǒng)一操作也很簡單。我們以crud操作為例,把crud集中到一個Action中。
步驟一、建立CRUDAction,內(nèi)容如下:

package com.asm; import com.opensymphony.xwork2.ActionSupport; public class CRUDAction extends ActionSupport {public String add() {return "success";}public String del() {return "success";}public String update() {return "success";}public String query() {return "success";} }

步驟二、配置此Action,為了清晰明了,專為此Action,建立一個配置文件crud.xml,主要內(nèi)容如下:

<struts><package name="crud" extends="struts-default" namespace="/crud"><action name="add" class="com.asm.CRUDAction" method="add"><result name="success">/crud/addSuccess.jsp</result></action><action name="del" class="com.asm.CRUDAction" method="del"><result name="success">/crud/delSuccess.jsp</result></action><action name="update" class="com.asm.CRUDAction" method="update"><result name="success">/crud/updateSuccess.jsp</result></action><action name="query" class="com.asm.CRUDAction" method="query"><result name="success">/crud/querySuccess.jsp</result></action></package> </struts>

分析:上面的method方法的值來源于CRUDAction中方法的名字,這樣當(dāng)我們訪問上面的每一個Action時,它實(shí)質(zhì)是和method指定的方法關(guān)聯(lián)上。

步驟三、把crud.xml配置文件并入struts.xml中,只需增加如下代碼:

<include file="crud.xml"></include>

步驟四、編寫相應(yīng)的jsp頁面,在此略去crud文件夾下的四個跳轉(zhuǎn)jsp頁面(addSuccess.jsp等),重點(diǎn)是crud.jsp頁面。內(nèi)容如下:

<html> <%String path=request.getContextPath(); %><body><a href="<%=path %>/crud/add.action">添加數(shù)據(jù)</a><br><a href="<%=path %>/crud/del.action">刪除數(shù)據(jù)</a><br><a href="<%=path %>/crud/query.action">查詢數(shù)據(jù)</a><br><a href="<%=path %>/crud/update.action">修改數(shù)據(jù)</a><br></body> </html>

?

補(bǔ)充擴(kuò)展,動態(tài)調(diào)用DMI不使用method實(shí)現(xiàn)統(tǒng)一.我們在crud.xml中增加如下內(nèi)容:

<action name="op" class="com.asm.CRUDAction"><result name="success">/crud/op.jsp</result> </action>

然后再在crud.jsp中定義如下鏈接:

<a href="<%=path %>/crud/op!add.action">添加數(shù)據(jù)</a><br> <a href="<%=path %>/crud/op!del.action">刪除數(shù)據(jù)</a><br> <a href="<%=path %>/crud/op!query.action">查詢數(shù)據(jù)</a><br> <a href="<%=path %>/crud/op!update.action">修改數(shù)據(jù)</a><br>

注意查看上面的鏈接地址,它們都是針對op action,然后再加地上“!+CRUDAction中相應(yīng)的方法名”,最后再寫上.action即可以訪問到統(tǒng)一頁面op.jsp。這樣做雖然能減少頁面,但是由于它們實(shí)質(zhì)用到的是同一個Action,所以這就意味著我們要使用的攔截器相同,相同的跳轉(zhuǎn)result。實(shí)際中這種方式很少使用,在此略作了解。如果不想使用動態(tài)方法調(diào)用,我們可以通過常量來關(guān)閉,即在struts.xml中增加如下配置:

<constant name="struts.enable.DynamicMethodInvocation" value="false"/>

?

擴(kuò)展2:在CRUDAction中使用do。舉例:我們在CRUDAction中增加一個新的方法,內(nèi)容如下:

public String doMain(){return "success";}

然后再在在crud.xml中增加如下內(nèi)容:

<action name="main" class="com.asm.CRUDAction" method="main"><result name="success">/crud/main.jsp</result> </action>

注意:配置中method屬性值是doMain中去掉do后M小寫。然后再在crud.jsp中增加如下鏈接:

<a href="<%=path %>/crud/main.action">main頁面</a><br>

隨后便可以訪問到.../crud/main.jsp頁面了。

?

8.使用ForwardAction實(shí)現(xiàn)頁面屏蔽。

我們在jsp頁面之間寫鏈接總會是.../xxx.jsp,而如果我們想屏蔽掉具體的jsp,只需要所jsp頁面配置成一個ForwardAction即可實(shí)現(xiàn)。示例如下:在根目錄下有一個index.jsp主頁,我們strtus.xml中作如下配置:

<package name="def" extends="struts-default"> <action name="forward"><result >/index.jsp</result></action> </package>

說明:如果沒有未action指定class,默認(rèn)就是ActionSupport類,如果沒有為action指定method屬性,則默認(rèn)執(zhí)行execute方法,如果沒有指定result的name屬性,默認(rèn)值為success。知道了這些再結(jié)合ActionSupport的源碼就不難理解實(shí)現(xiàn)轉(zhuǎn)發(fā)的原理了。

?

隨后再在前面第7點(diǎn)擴(kuò)展中用到的op.jsp中增加如下代碼:

<a href="<%=request.getContextPath()%>/forward.action">forward</a>

最后再測試訪問op.jsp,在op.jsp中頁面中直接點(diǎn)鏈接便可以跳到index.jsp,觀察地址欄發(fā)現(xiàn)此時跳到index頁面是進(jìn)行的服務(wù)器跳轉(zhuǎn),如果我們在上面的配置中的result增加type屬性變成

<result type="redirect">/index.jsp</result>

,實(shí)現(xiàn)的跳轉(zhuǎn)就是客戶端跳轉(zhuǎn)。

補(bǔ)充:像這種forward形式的action實(shí)質(zhì)是執(zhí)行的ActionSupport 這個Action。因此配置它的result可以參看此類的api文檔,比如它常用的result name有:success、login、input等。

?

9.使用default-Action配置統(tǒng)一訪問

default-action-ref,當(dāng)訪問沒有找到對應(yīng)的action時,默認(rèn)就會調(diào)用default-action-ref指定的action.同樣在上面的package中增加如下內(nèi)容

<default-action-ref name="error"></default-action-ref><action name="error"><result>/other/error.jsp</result></action>

上面一段內(nèi)容就是說當(dāng)我們訪問的action不能被找到時便指向名為error的action中去,接著我們在下面配置了這個error Action。但是要注意,一個package內(nèi)只配置一個<default-action-ref>,如果配置多個,就無法預(yù)測結(jié)果了. 此時我們只要輸入.../myStruts2/luanFangWen.action這樣的形式,它就會去訪問這個默認(rèn)的<default-action-ref>,通常我們會為它配置一個錯誤頁面,以提示用戶訪問的頁面不存在。

?

在web開發(fā)中,我們還可以把這個默認(rèn)的action訪問配置成主頁,這樣當(dāng)用戶訪問一些不存在的action時,總會跳到主頁上去。

通過此配置,只要是訪問一個不存在的action便會轉(zhuǎn)向到.../other目錄下的error.jsp頁面。但是如果訪問是其它的不存在資源則仍是報tomcat所標(biāo)識的404錯誤,我們可以在web.xml中作如下配置:

<error-page><error-code>404</error-code><location>/other/404error.jsp</location> </error-page>

這樣配置后,訪問錯誤頁面將跳到.../other/404error.jsp頁面中去。

補(bǔ)充說明:如果我們用ie訪問時,如果選中了[工具][IE選項(xiàng)][高級][瀏覽][顯示友好的http錯誤信息],則配置的錯誤頁面將失效,因?yàn)檎也坏劫Y源時會報HTTP404錯誤,而ie截取到此錯誤進(jìn)行了它自身的友好處理,所以我們設(shè)置<error-page>就失效。

?

?

10.使用通配符

建立struts2wildcard項(xiàng)目,此實(shí)例基本仿照前面前面第7點(diǎn)的實(shí)例改寫而成。為了使用通配符,只需要改寫配置文件即可。此實(shí)例未使用通配時的配置文件如下:

<action name="addUser" class="com.asm.UserAction" method="addUser"><result name="success">/user/addUser.jsp</result> </action> <action name="delUser" class="com.asm.UserAction" method="delUser"><result name="success">/user/delUser.jsp</result> </action> <action name="queryUser" class="com.asm.UserAction" method="queryUser"><result name="success">/user/queryUser.jsp</result> </action> <action name="updateUser" class="com.asm.UserAction" method="updateUser"><result name="success">/user/updateUser.jsp</result> </action>

我們注釋掉上面的配置,使用通配符只需如下內(nèi)容即可達(dá)到相同的效果:

<action name="*User" class="com.asm.UserAction" method="{1}User"><result name="success">/user/{1}User.jsp</result> </action>

原理:當(dāng)有.../addUser.action請求時,如果不能在當(dāng)前應(yīng)用中找到完全相同的addUser名字的Action時,通配符配置這時就起作用了,按通配原則,它便和上面的name="*User"相配成功,這里不難明了*此時代指的內(nèi)容是add,再來看method恰恰是引用第一個*的內(nèi)容,所以它的method此時的完整名為addUser,它剛好和com.asmUserAction中的addUser方法相對,所以它會去addUser方法,再來看下面的result配置所指代的頁面,它也用到了{(lán)1},所以它的完整頁面是/addUser.jsp。其實(shí)如果我們有良好的編程命名習(xí)慣,所有的Action我們都只需要進(jìn)行一次配置。

?

舉例:規(guī)定所有的Action類都用XXXAction來命名,類中所有的CRUD方法都用add/del/update/query。Jsp頁面也用add/del/update/query_XXX.jsp這樣的形式。即配置文件可以寫成如下形式:

<action name="*_*" class="com.asm.{2}Action" method="{1}"><result name="success">.../{1}_{2}.jsp</result> </action>

Name中第一個*代表CRUD操作的名字,第二個*代表類的名字。所以訪問鏈接地址舉例如下:

.../del_User.action將訪問到User類的del方法,成功后跳到del_User.jsp頁面。補(bǔ)充說明{0}是代表name中所有的*組合。

?

11.使用0配置:ZERO Annotation

?

12.Result配置詳解

說明:在前面的許多案例中我們所用到的Action基本都繼承自ActionSupport這個類,而在這個類中我們定義了五個字段:SUCCESS,NONE,ERROR,INPUT,LOGING。我們可以直接返回這些字段值,這些字段值實(shí)質(zhì)是被定義成:String SUCCESS=”success”這樣的形式,所以我們只要在Result元素中用它們的小寫即可。
<result>標(biāo)準(zhǔn)完整形式如下:

<result name="success" type="dispatcher"><param name="location">/default.jsp</param> </result>

如果我們都采用默認(rèn)的形式,最終可以簡寫成:<result>/default.jsp</result>

探討type類型

Type類型值

作用說明

對應(yīng)類

chain

用來處理Action鏈

com.opensymphony.xwork2.ActionChainResult

dispatcher

用來轉(zhuǎn)向頁面,通常處理JSP

org.apache.struts2.dispatcher.ServletDispatcherResult

redirect

重定向到一個URL

org.apache.struts2.dispatcher.ServletRedirectResult

redirectAction

重定向到一個Action

org.apache.struts2.dispatcher.ServletActionRedirectResult

plainText

示源文件內(nèi)容,如文件源碼

org.apache.struts2.dispatcher.PlainTextResult

freemarker

處理FreeMarker模板

org.apache.struts2.views.freemarker.FreemarkerResult

httpheader

控制特殊http行為的結(jié)果類型

org.apache.struts2.dispatcher.HttpHeaderResult

stream

?

向?yàn)g覽器發(fā)送InputSream對象,通常用來處理文件下載,還可用于返回AJAX數(shù)據(jù)。

?

org.apache.struts2.dispatcher.StreamResult

?

velocity

處理Velocity模板

org.apache.struts2.dispatcher.VelocityResult

xslt ??

??處理XML/XLST模板

?org.apache.struts2.views.xslt.XSLTResult

?

以上對type類型作簡要的說明,下面來看實(shí)例:當(dāng)一個Action處理后要返回的Result是另一個Action時,作如何配置,關(guān)鍵就是配置type類型。下面建立struts2result項(xiàng)目說明
步驟一:建立兩個Action:TestAction、Test2Action
步驟二:web.xml配置省略。struts.xml主要配置內(nèi)容如下:

<struts><package name="resultTest" extends="struts-default"><action name="test" class="com.asm.TestAction"><result name="success" type="chain"><param name="actionName">test2</param></result></action><action name="test2" class="com.asm.Test2Action"><result name="success">/test2Suc.jsp</result></action> </package> </struts>

說明:在名為“test”的action中,我們配置result元素的type類型值為chain,意為將繼續(xù)把Action傳遞到下一個名為test2的Action中去,在test2.action中會把頁面轉(zhuǎn)向到test2Suc.jsp中去。

在type類型為chain時,它的param有4個值可配,除了這里用到的name=”actionName”外(必須配置,否則報錯),還有name=namespace|method|skipActions。其中namespace指定要轉(zhuǎn)向到action的名字空間,由于此處是轉(zhuǎn)到Action位于同一個namespace下,而namesapace的默認(rèn)值the current namespace,所以可以省略不寫(需要說明的是如果要跳到別的名稱空間的action中去,除了使用namespace指定外,還可以用:/要跳去action所在名稱空間的值/要跳去的action的name值)。Method用于指定轉(zhuǎn)向到一個目標(biāo)action所調(diào)用的方法,默認(rèn)是調(diào)用下一個action的execute方法,所以此處仍可以省略。SkipActions是一個可選的屬性,一般不用。具體可以參看chain所對應(yīng)類的api幫助

?

在本實(shí)例中,我們還在TestAction中設(shè)定一個username字段,并在execute方法執(zhí)行為它賦了值,并在test2Suc.jsp中引用了此值。其實(shí)這種做法在web開發(fā)中還是很有用處,比如可以代替隱藏域需要注意的是之所以在action的傳遞中能把設(shè)定的這個值保存下去主要是因?yàn)檗D(zhuǎn)向都是服務(wù)器跳轉(zhuǎn)。如果我們跳轉(zhuǎn)時采取了客戶端跳轉(zhuǎn),比如在test2 action的result中指定type類型為redirect,要想傳遞參數(shù)可以在result指向的jsp頁面中附加參數(shù)即可,我們可以在test2 action的result中寫成:

<result name="success" type="redirect"> /test2Suc.jsp?username=${username} </result>

?

隨后在test2Suc.jsp頁面中引用時會出現(xiàn)三個問題:

1.EL表達(dá)式引用失效,(EL表達(dá)式應(yīng)該使用${param.username}形式)。我們也可以使用<%=request.getParameter("username")%>獲取參數(shù)值。?

2.由于在前面的TestAction中設(shè)定的值為中文,而附加到這里的uri請求的參數(shù)后面時會出現(xiàn)亂碼問題。(可以使用URI編碼再解碼解決此問題)

3.值棧取值失效:因?yàn)槊恳淮蝦equest共享同一個值棧,所以服務(wù)器端的forward跳轉(zhuǎn)也是能共享同一值棧得。但是著當(dāng)test action執(zhí)行后把請求交由test2 action時,test2 action采取的是redirect重定向到test2Suc.jsp頁面,這時其實(shí)就是重發(fā)的一次request,所以在test action保存的值棧內(nèi)容全部失效。這也就是為什么我們要附加參數(shù)的原因。而參數(shù)是保存在actionContext中,所以采用了#的方式來取出值。圖示說明:

步驟三,編寫鏈接頁面index.jsp。發(fā)布測試:

?

全局result

如果我們所有的action均有可能跳到相同的頁面,則不防使用全局result。為了方便引用我們專門建立一個package來存放公共的result。在會用到個全局的跳轉(zhuǎn)時,只需要把繼承自這個公共的package即可。

建立公共包,代碼如下:

<package name="pubResult" extends="struts-default" abstract="true"><global-results><result name="error">/error.jsp</result></global-results> </package>

由于它下面沒的action配置,所以我們可以像默認(rèn)的struts-default包一樣,聲明abstract=true,這樣聲明表示此packgage下不會有action,它一般是用來讓別的package繼承。隨后再在要用到全局result中引用這個公共的package。代碼如下:

<package name="testGlobal" extends="pubResult" ><action name="error" class="com.asm.ErrorAction"></action><action name="error2" class="com.asm.Error2Action"></action> </package>

這樣操作相當(dāng)于把全局的result加到了此package下的所有action中去。

?

動態(tài)Result:了解

步驟一:建立DynaAction,主要代碼如下:

package com.asm; public class DynaAction extends ActionSupport {private String username;private String nextAction;public String execute() throws Exception {if (username.equals("admin")) {nextAction = "admin";} else if (username.equals("user")) {nextAction = "user";} else {nextAction = ERROR;}return SUCCESS;}...省略get/set方法 }

步驟二、建立jsp頁面dyna.jsp,主要是為了向DynaAction中傳遞username參數(shù)。

步驟三、相關(guān)配置如下:

<package name="dynaTest" extends="pubResult"><action name="dyna" class="com.asm.DynaAction"><result name="success" type="chain">${nextAction}</result></action><action name="admin" ><result>/admin.jsp</result></action><action name="user"><result>/user.jsp</result></action> </package>

分析:當(dāng)dyna.jsp把參數(shù)傳遞到DynaAction中去時,如果傳遞的值為admin,我們便設(shè)定了nextAction的值admin,在配置文件中我們通過${nextAction}(用在struts配置文件中的ognl,其實(shí)nextAction的值是存在值棧中,我們通過${}這樣的形式取出。在此只作了解)來獲取值便為admin,隨后再繼續(xù)把請求傳遞到下一個Action中去(此時也即admin.action),為了方便我們設(shè)定了兩個ForwardAction:admin.action和user.action。這樣便可以跳到指定的jsp頁面。 原理:dyna.action執(zhí)行后會繼續(xù)把請求傳遞給下一個Action,而下一個Action的到底是哪一個Action,是通過DynaAction中動態(tài)指定的,比如這里是根據(jù)傳遞的username的值指定。

?

?

13.異常處理

步驟一、建立struts2exception項(xiàng)目下,在該項(xiàng)目下建立登錄頁面login.jsp。主要代碼如下:

<form action="<%=request.getContextPath() %>/login.action">username:<input type="username" name="username"><br><input type="submit" value="login"> </form>

步驟二、建立LoginAction,代碼如下:

package com.asm; public class LoginAction extends ActionSupport {private String username;public String execute() throws Exception {if (username.equals("exception")) {throw new ClassNotFoundException("類未被找到");} else if (username.equals("global")) {throw new Exception("全局異常");} else {return SUCCESS;}}...省力get/set方法 }

步驟三、struts.xml配置文件如下:

<struts><package name="ex" extends="def"><action name="login" class="com.asm.LoginAction"><exception-mapping result="myException"exception="java.lang.ClassNotFoundException"></exception-mapping><result name="myException">/exception.jsp</result><result name="success">/main.jsp</result></action></package><package name="def" extends="struts-default" abstract="true"><global-results><result name="myGlobal">/globalException.jsp</result></global-results><global-exception-mappings><exception-mapping result="myGlobal"exception="java.lang.Exception"></exception-mapping></global-exception-mappings></package> </struts>

分析

1.異常處理機(jī)制較為簡單,所以在此只略作說明。當(dāng)?shù)卿洉r輸入“exception”時,在LoginAction中會拋出會一個ClassNotFoundException異常,此異常我們采取的局部異常處理的方式,如果登錄時輸入“globla”,則會拋出Exception異常,此異常我們采取的是全局異常的處理方式,

2.在ex包中我們繼承了全局異常所在的包。提示:<exception-mapping>中的result屬性的值來源于<result>元素中的name屬性的值。從實(shí)例可以看出,我們一般把這種全局性的異常放在一個抽象包中供其實(shí)包繼承。

?

小結(jié)Action

在struts2中一個普通的java類只要有public String execute()這樣的方法都可以配置成一個Action,另外我們可以實(shí)現(xiàn)Action接口來使java類成為一個Action,但通常的做法是繼承ActionSupport類,這也是以后的項(xiàng)目中慣用的方法,也是推薦的首選方法。 與struts1.x不同的是:在struts2中每一個Action被請求訪問時都會new出這個Action對象,所以Action本身不存在線程安全的問題。

?

項(xiàng)目代碼:http://pan.baidu.com/s/1pJkfxnt

?

總結(jié)

以上是生活随笔為你收集整理的struts2.1.6教程二、struts.xml配置及例程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。