避免重復(fù)提交這個(gè)問題在Web應(yīng)用開發(fā)領(lǐng)域應(yīng)該是一個(gè)老生常談的問題了,主流的一些Web應(yīng)用框架也提供了方便使用的功能來實(shí)現(xiàn)這個(gè)需求,比如Struts的Token。但是有些時(shí)候,可能用戶確實(shí)需要刷新提交之后所轉(zhuǎn)到的頁(yè)面,比如假設(shè)如下的需求:用戶注冊(cè)了一個(gè)賬號(hào),但是這個(gè)賬號(hào)需要管理員批準(zhǔn)才可以進(jìn)行工作,于是,用戶在注冊(cè)頁(yè)面填寫了詳細(xì)信息之后,提交,轉(zhuǎn)到詳細(xì)信息頁(yè)面,然后刷新這個(gè)頁(yè)面來查看自己的狀態(tài)。此時(shí),我覺得使用redirect是非常方便的。
以下是redirect在Struts1和Struts2中的實(shí)現(xiàn):
Struts1:
在Struts1中,有一個(gè)org.apache.struts.action.ActionRedirect的類,這個(gè)類是ActionForward類的子類,是專門用來做redirect跳轉(zhuǎn)的。使用起來非常的簡(jiǎn)單,只需在你的Action類的方法中,返回一個(gè)ActionRedirect類的實(shí)例即可。
----------------------------------------------------
ActionRedirect redirect = new ActionRedirect(mapping.findForward("detailAction")); // 這里是在struts-config.xml文件中定義的<forward>節(jié)點(diǎn)的name屬性
redirect.addParameter("id", user.getId()); //這里是要在url后面附加的參數(shù)名稱及其值
return redirect;
----------------------------------------------------
Struts2:
在Struts2中,情況有所不同。但是Struts2里面的方式,更加的合理,因?yàn)椴恍枰贏ction代碼中編碼來完成,完全是通過配置完成的。在配置文件struts.xml中,
----------------------------------------------------
<action name="userCreate" method="create" class="lab.action.UserAction">
<result name="detailAction" type="redirect-action">
<param name="actionName">userDetail</param>
<param name="namespace">/</param>
<param name="parse">true</param>
<param name="user.id">${user.id}</param>
</result>
</action>
<action name="userDetail" method="detail" class="lab.action.UserAction">
<result name="detailPage">userDetail.jsp</result>
</action>
----------------------------------------------------
這里,userCreate是創(chuàng)建用戶的Action,userDetail是查看用戶詳細(xì)信息的Action,都是由類lab.action.UserAction來提供工作。如果從一個(gè)action redirect到另外一個(gè)action,那么redirect的result的type為redirect-action。
其中,參數(shù)actionName為要跳轉(zhuǎn)到的action的name,無(wú)需.action后綴,struts框架會(huì)根據(jù)你配置的屬性來確定后綴是什么。namespace為搜索action時(shí)使用的命名空間。parse是表示要對(duì)參數(shù)進(jìn)行解析。后面的幾個(gè)參數(shù)就是根據(jù)實(shí)際需要來定義參數(shù)名稱和參數(shù)的值,這里會(huì)由struts框架將這些參數(shù)附加到URL后面。例如在上面的例子中,user.id為參數(shù)名,${user.id}為參數(shù)值,該值通過解析userCreate對(duì)應(yīng)的類中的user屬性的id屬性來得到,和在jsp頁(yè)面使用方式相同,其實(shí)都是來自于Value Stack。
如果是要redirect到一個(gè)jsp頁(yè)面,并且?guī)в袇?shù)(這種情況應(yīng)該很少),按照struts2的文檔描述:
----------------------------------------------------
<result name="success" type="redirect"><param name="location">foo.jsp</param><param name="parse">false</param></result>
<package name="passingRequestParameters" extends="struts-default" namespace="/passingRequestParameters"><-- Pass parameters (reportType, width and height) --><!--The redirect-action url generated will be :/genReport/generateReport.jsp?reportType=pie&width=100&height=100--><action name="gatherReportInfo" class="..."><result name="showReportResult" type="redirect"><param name="location">generateReport.jsp</param><param name="namespace">/genReport</param><param name="reportType">pie</param><param name="width">100</param><param name="height">100</param></result></action></package>
----------------------------------------------------
另外,對(duì)于比如查詢統(tǒng)計(jì)這樣的功能,用戶刷新頁(yè)面的幾率是非常大的,這種情況下,建議使用get方式來提交form,以避免IE那個(gè)總是跳出來的對(duì)話框。
相比于forward方式的跳轉(zhuǎn)而言,redirect的跳轉(zhuǎn)會(huì)在瀏覽器地址欄暴露更多的信息,可能會(huì)被使用者惡意篡改,所以在使用redirect的時(shí)候,要對(duì)數(shù)據(jù)在后臺(tái)進(jìn)行更加嚴(yán)格和全面的校驗(yàn)。
以下是實(shí)驗(yàn)代碼的鏈接,在壓縮包中,去掉了struts相關(guān)的lib包,如果要在本地運(yùn)行這個(gè)實(shí)驗(yàn)應(yīng)用,只需把對(duì)應(yīng)struts版本的struts<version>-blanck-<version>.war里面的lib目錄下的jar文件取出則可。
實(shí)驗(yàn)在Windows XP SP2, resin-3.2.1, Sun JDK 1.5, struts 1.2.9/struts 2.0.11.1下運(yùn)行通過。如果是使用struts1,需要把應(yīng)用編譯成Java 1.4格式的(如果是使用Eclipse,只需修改應(yīng)用的compile level即可)。
聯(lián)系客服