Struts2中防止表單重複提交的兩種方式

防止表單重複提交,這是個很重要的知識點,而且很有用。當用戶提交了一個表單,此時,地址欄顯示的是處理這個表單的Action的地址,若此時刷新,則會重新發送一次表單數據,即又進行了一次提交,若這個Action是用來處理用戶註冊的,那麼重複提交會再一次向數據庫中插入之前已經插入的數據,這顯然不是我們想要的。有兩種方法,可以防止表單重複提交,一種是用Action的重定向,一種是用Session Token(Session令牌)。

第一種方法,Action處理完用戶提交的數據後,重定向到另一個Action或是一個頁面,使用戶提交後,所停留的位置,不是當前處理數據的Action,這樣用戶再刷新時,就不會再次執行這個Action了,就會避免表單重複提交的問題了。

第二種方法,是一種很經典的處理這個問題的機制。這種方法是在用戶要提交的表單中,加入一個<s:token>標籤,這樣,當瀏覽器第一次訪問這個帶有<s:token>標籤的頁面時,在服務器中,解析<s:token>標籤的類(TokenTag.class),會生成一個隨機的字符串(這個字符串,查看網頁的源代碼可以看到),並且發送給客戶端的瀏覽器,同時,在服務器中,會把這個隨機字符串保存到用戶的session對象中。當第一次提交表單時,在服務器中,會比較客戶端和服務器中分別保存的這個隨機字符串,因爲是第一次提交,所以這兩個字符串相等,然後進行正常的業務處理。第一次提交後,在服務器中的session中保存的這個隨機字符串,會改變爲其他的隨機值,注意,這是很重要的一步!此時,地址欄停留在處理用戶提交數據的Action中,客戶端中保存的隨機字符串沒有改變,若是刷新頁面,即重複提交,服務器再進行兩個字符串的比較,會不相等,就會跳轉到name爲invalid.token的結果頁面中,這樣就會防止表單重複提交了。

第一種方法的舉例,在上一篇博客中,這裏就不再列出了,這裏主要舉例說明一下session token的機制:

[html] view plain copy
  1. Login.jsp:  
  2.   
  3. <s:form action="/test/token" theme="simple">  
  4.         username:<s:textfield name="username"></s:textfield><br>  
  5.         password:<s:password name="password"></s:password><br>  
  6.         <s:submit value="submit"></s:submit>  
  7.         <s:token></s:token><!--一定要有這個標籤-->  
  8.     </s:form>  
[html] view plain copy
  1. struts.xml:  
  2.   
  3. <action name="token" class="com.suo.actions.TokenAction">  
  4.             <result name="success">/WEB-INF/result/LoginResult.jsp</result>  
  5.             <result name="invalid.token">/WEB-INF/result/TokenFailed.jsp</result>  
  6.             <!-- 若重複提交,則會跳轉到這個頁面,注意這裏result的名字,一定要是invalid.token -->  
  7.               
  8.             <interceptor-ref name="token"></interceptor-ref>  
  9.             <interceptor-ref name="defaultStack"></interceptor-ref>  
  10.             <!-- 這裏一定要有這兩個攔截器 -->  
  11.         </action>  
[java] view plain copy
  1. TokenAction.java:  
  2.   
  3. package com.suo.actions;  
  4.   
  5. import java.util.Map;  
  6.   
  7. import javax.servlet.http.HttpServletRequest;  
  8. import javax.servlet.http.HttpSession;  
  9.   
  10. import org.apache.struts2.ServletActionContext;  
  11.   
  12. import com.opensymphony.xwork2.ActionContext;  
  13. import com.opensymphony.xwork2.ActionSupport;  
  14.   
  15. public class TokenAction extends ActionSupport {  
  16.     private String username;  
  17.     private String password;  
  18.       
  19.     public String getUsername() {  
  20.         return username;  
  21.     }  
  22.     public void setUsername(String username) {  
  23.         this.username = username;  
  24.     }  
  25.     public String getPassword() {  
  26.         return password;  
  27.     }  
  28.     public void setPassword(String password) {  
  29.         this.password = password;  
  30.     }  
  31.       
  32.     public String execute()  
  33.     {     
  34.         return SUCCESS;  
  35.     }  
  36. }  


結果頁面就不寫了

原博文地址: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.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章