Struts2中防止表單重複提交的兩種方式
防止表單重複提交,這是個很重要的知識點,而且很有用。當用戶提交了一個表單,此時,位址列顯示的是處理這個表單的Action的地址,若此時重新整理,則會重新發送一次表單資料,即又進行了一次提交,若這個Action是用來處理使用者註冊的,那麼重複提交會再一次向資料庫中插入之前已經插入的資料,這顯然不是我們想要的。有兩種方法,可以防止表單重複提交,一種是用Action的重定向,一種是用Session Token(Session令牌)。
第一種方法,Action處理完使用者提交的資料後,重定向到另一個Action或是一個頁面,使使用者提交後,所停留的位置,不是當前處理資料的Action,這樣使用者再重新整理時,就不會再次執行這個Action了,就會避免表單重複提交的問題了。
第二種方法,是一種很經典的處理這個問題的機制。這種方法是在使用者要提交的表單中,加入一個<s:token>標籤,這樣,當瀏覽器第一次訪問這個帶有<s:token>標籤的頁面時,在伺服器中,解析<s:token>標籤的類(TokenTag.class),會生成一個隨機的字串(這個字串,檢視網頁的原始碼可以看到),並且傳送給客戶端的瀏覽器,同時,在伺服器中,會把這個隨機字串儲存到使用者的session物件中。當第一次提交表單時,在伺服器中,會比較客戶端和伺服器中分別儲存的這個隨機字串,因為是第一次提交,所以這兩個字串相等,然後進行正常的業務處理。第一次提交後,在伺服器中的session中儲存的這個隨機字串,會改變為其他的隨機值,注意,這是很重要的一步!
第一種方法的舉例,在上一篇部落格中,這裡就不再列出了,這裡主要舉例說明一下session token的機制:
- Login.jsp:
- <s:formaction="/test/token"theme="simple">
-
username:<s:textfieldname="username"></s:textfield
- password:<s:passwordname="password"></s:password><br>
- <s:submitvalue="submit"></s:submit>
- <s:token></s:token><!--一定要有這個標籤-->
- </s:form>
- struts.xml:
- <actionname="token"class="com.suo.actions.TokenAction">
- <resultname="success">/WEB-INF/result/LoginResult.jsp</result>
- <resultname="invalid.token">/WEB-INF/result/TokenFailed.jsp</result>
- <!-- 若重複提交,則會跳轉到這個頁面,注意這裡result的名字,一定要是invalid.token -->
- <interceptor-refname="token"></interceptor-ref>
- <interceptor-refname="defaultStack"></interceptor-ref>
- <!-- 這裡一定要有這兩個攔截器 -->
- </action>
- TokenAction.java:
- package com.suo.actions;
- import java.util.Map;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpSession;
- import org.apache.struts2.ServletActionContext;
- import com.opensymphony.xwork2.ActionContext;
- import com.opensymphony.xwork2.ActionSupport;
- publicclass TokenAction extends ActionSupport {
- private String username;
- private String password;
- public String getUsername() {
- return username;
- }
- publicvoid setUsername(String username) {
- this.username = username;
- }
- public String getPassword() {
- return password;
- }
- publicvoid setPassword(String password) {
- this.password = password;
- }
- public String execute()
- {
- return SUCCESS;
- }
- }
結果頁面就不寫了
原博文地址:http://blog.csdn.net/hackerain/article/details/6990121
PS:
Struts2 解決表單的重複提交問題:(兩種方式:①Action的重定向②如下)
I. 在 s:form 中新增 s:token 子標籤
> 生成一個隱藏域
> 在 session 新增一個屬性值
> 隱藏域的值和 session 的屬性值是一致的.
II. 使用 Token 或 TokenSession 攔截器.
> 這兩個攔截器均不在預設的攔截器棧中, 所以需要手工配置一下
> 若使用 Token 攔截器, 則需要配置一個 token.valid 的 result
> 若使用 TokenSession 攔截器, 則不需要配置任何其它的 result
III. Token VS TokenSession
> 都是解決表單重複提交問題的
> 使用 token 攔截器會轉到 token.valid 這個 result
> 使用 tokenSession 攔截器則還會響應那個目標頁面, 但不會執行 tokenSession 的後續攔截器. 就像什麼都沒發生過一樣!
IV. 可以使用 s:actionerror 標籤來顯示重複提交的錯誤訊息.
該錯誤訊息可以在國際化資原始檔中覆蓋. 該訊息可以在 struts-messages.properties 檔案中找到
struts.messages.invalid.token=The form has already been processed or no token was supplied, please try again.