struts2防止表單重複提交以及刷新瀏覽器重複訪問後臺的解決方案

一、造成重複提交主要的兩個原因:


   在平時的開發過程中,經常可以遇到表單重複提交的問題,如做一個註冊頁面,如果表單重複提交,那麼一個用戶就會註冊多次,重複提交主要由於兩種原因。  
  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>

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