一、造成重複送出主要的兩個原因:
在平時的開發過程中,經常可以遇到表單重複送出的問題,如做一個注冊頁面,如果表單重複送出,那麼一個使用者就會注冊多次,重複送出主要由于兩種原因。
1、 一是,伺服器處理時間久。當使用者在表單中填完資訊 ,點選“送出”按鈕後,由于伺服器反應時間過長沒能及時看到響應資訊,或者出于其它目的,再次點 擊“提 交”按鈕,進而導緻在伺服器端接收到兩條或多條相同的資訊。如果資訊需要存儲到背景資料庫中,如此以來就 會産生資料庫操作異常提示資訊,以至于給使用者帶來 錯誤資訊提示,進而給使用者的使用帶來不便。
2、二是,forward跳轉引起的重複送出。在頁面跳轉的時候,有兩種類型:請求轉發和重定向,所謂請求轉發是在伺服器端進行跳轉,對使用者是透明的,此時浏覽器中的位址不會發生改變,重定向是在用戶端發生跳轉,跳轉時候浏覽器中的位址欄會發生改變,如果我們在注冊時,使用了請求轉發,那麼當我們重新整理頁面時,就會引起表單的重複送出
二、解決方案
方案一、使用struts2中的token攔截器或者tokenSession攔截器
對token的簡單了解:
1)當使用者首次通路包含表單的頁面時,伺服器會在這次會話中建立一個session對象,并産生一個令牌值,然後将這個令牌值作為隐藏輸入域的值,随表單一起發送到伺服器端,同時将令牌值儲存到Session中。
2) 當使用者送出頁面時,伺服器首先判斷請求參數中的令牌值和Session中儲存的令牌值是否相等,若相等,則清楚Session中的令牌值,然後執行資料處 理操作。如果不相等,則提示使用者已經送出過了表單,同時産生一個新的令牌值,儲存到Session中。當使用者重新通路送出資料頁面時,将新産生的令牌值作 為隐藏輸入域的值。
####
token: 在活動Action中檢查合法令牌(token), 防止表單的重複送出;
token-session: 同上, 但是在接到非法令牌時将送出的資料儲存在session中;
主要步驟如下:
第一步:在表單中加入<s:token />(當然啦!要首先導入struts2的标簽庫 <%@taglib uri="/struts-tags" prefix="s" %>)
<s:form action="helloworld_other" method="post" namespace="/test">
<s:textfield name="person.name"/><s:token/><s:submit/>
</s:form>
第二步:在struts.xml配置檔案中相應的action上配置token攔截器或者tokenSession攔截器。此攔截器隻能用在有form的送出請求上。
<action name="helloworld_*" class="com.jim.action.HelloWorldAction" method="{1}">
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="token" />
<result name="invalid.token">/WEB-INF/page/message.jsp</result>
<result>/WEB-INF/page/result.jsp</result>
</action>
以上配置加入了“token”攔截器和“invalid.token”結果,因為“token”攔截器在會話的token與請求的token不一緻時,将會直接傳回“invalid.token”結果。
方案二:基于第二種重複送出表單的原因,伺服器内部使用重定向
在Struts2中的struts.xml中,result标簽的type預設值是 dispatcher,(請求轉發),要實作以上的功能,肯定不能使用預設值,我們需要将其值設為redirectAction(重定向到某一 Action),也就是說重一個Action跳轉到另外一個Action,此時浏覽器中的位址是第二個Action,結合到上面的需求,我們可以再第一個 Action中将記錄添加到資料庫中,然後在第二個Action中将資料讀取出來。以後每次重新整理,那麼隻會執行第二個Action。
到struts-default.xml中找到與redirectionAction對應的一個類,ServletActionRedirectResult
從Api文檔中發現找出裡面有一個字段叫做actionName,指定我們需要跳轉的Action
配置方法如下:
<action name="add" class="com.action.AddAction">
<result name="success" type="redirectAction">
<param name="actionName">show_show</param>
</result>
</action>
至于第二個Action的配置方法,相信學過struts2的同學都會