我的漫漫程序之旅

          專注于JavaWeb開發
          隨筆 - 39, 文章 - 310, 評論 - 411, 引用 - 0
          數據加載中……

          Struts2.1 annotation防止表單重復提交

          問題描述:用戶提交表單時可能因為網速的原因,或者網頁被惡意刷新,致使同一條記錄重復插入到數據庫中,這是一個比較棘手的問題。我們可以從客戶端和服務器端一起著手,設法避免同一表單的重復提交。
          解決方案:

          1.使用客戶端腳本
          提到客戶端腳本,經常使用的是JavaScript進行常規輸入驗證。在下面的例子中,我們使用它處理表單的重復提交問題,請看下面的代碼:
             

           

          <form method="post" name="register" action="test.php" enctype=
          "multipart/form-data"
          > 
          <input name="text" type="text" id="text" />
          <input name="cont" value="提交" type="button" onClick="document.
          register.cont.value='正在提交,請等待';document.register.cont.
          disabled=true;document.the_form.submit();"
          > 
          </form>

           

          上述方法,主要是將按鈕的提交狀態改變為disabled。

           

          2.利用Struts2的令牌機制。
          防止表單重復提交主要用的到標簽是<s: token />,攔截器 <interceptor-ref name="token" />,還有一個默認的返回值<result name="invalid.token">/input.jsp</result>

          在頁面加載時,<s: token />產生一個GUID(Globally Unique Identifier,全局唯一標識符)值的隱藏輸入框如:
          <input type="hidden" name="struts.token.name" value="struts.token"/>
          <input type="hidden" name="struts.token" value="BXPNNDG6BB11ZXHPI4E106CZ5K7VNMHR"/>
          同時,將GUID放到會話(session)中;在執行action之前,“token”攔截器將會話token與請求token比較,如果兩者相同,則將會話中的token刪除并往下執行,否則向actionErrors加入錯誤信息。如此一來,如果用戶通過某種手段提交了兩次相同的請求,兩個token就會不同。
          下面用零配置來演示 token的作用
          /WEB-INF/content/test-success.jsp

          <%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%>
          <%@ taglib prefix="s" uri="/struts-tags" %>
          <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
          <html>
          <head>
          </head>


              
          <body>
                 
          <s:actionerror/>
                 
          <s:form action="test!save.action" method="POST">
                     
          <s:textfield name="message" label="請輸入您的信息"/>
                     
          <s:token name="token"/>
                     
          <s:submit value="確定" />
                 
          </s:form>
              
          </body>
          </html>

          /WEB-INF/content/error.jsp

          <%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%>
          <%@ taglib prefix="s" uri="/struts-tags" %>
          <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
          <html>
          <body>
          <s:actionerror/>
              不能重復提交表單!
          </body>
          </html>

           

          /WEB-INF/content/test-ok.jsp

           

          <%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%>
          <%@ taglib prefix="s" uri="/struts-tags" %>
          <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
          <html>
              
          <body>
                 SAVE OK!
              
          </body>
          </html>

          TestAction.java

          package com.fun.actions;


          import org.apache.struts2.convention.annotation.InterceptorRef;
          import org.apache.struts2.convention.annotation.Result;
          import org.apache.struts2.convention.annotation.Results;


          import com.opensymphony.xwork2.ActionSupport;
          @Results(
          {
          @Result(name
          ="invalid.token",location="/index.html",type="redirect")}
          )
          @InterceptorRefs(
          {@InterceptorRef(value="token",params={"includeMethods","save"}),@InterceptorRef("defaultStack") })
          public class TestAction extends ActionSupport {
              
          private String message;
              
          public String execute(){
              
          return SUCCESS;
              }

              



              
          public String save(){
              
          return "ok";
              }

              
          public String getMessage() {
                 
          return message;
              }

              
          public void setMessage(String message) {
                 
          this.message = message;
              }

              
          }


          其實,最主要的就是 token攔截器中還有 includeMethods()這個方法,表示的是,Action中的哪個方法需要經過攔截器。屬性excludeMethods()這個方法表示的是哪個方法不經過攔截器。如果,沒有加上“defaultStack”這個攔截器的話,則ActionContext的值將為null。

          posted on 2010-12-24 16:09 々上善若水々 閱讀(3373) 評論(1)  編輯  收藏 所屬分類: Struts2

          評論

          # re: Struts2.1 annotation防止表單重復提交  回復  更多評論   

          謝謝
          2013-10-27 22:50 | 訂單
          主站蜘蛛池模板: 台北县| 龙陵县| 双流县| 台东县| 珠海市| 刚察县| 手游| 石狮市| 南漳县| 丹江口市| 西吉县| 嘉义市| 华池县| 荔波县| 礼泉县| 新津县| 海丰县| 黎川县| 海盐县| 酉阳| 西充县| 南丰县| 河西区| 惠州市| 盱眙县| 鲁甸县| 札达县| 邳州市| 叙永县| 永泰县| 文化| 龙泉市| 仁化县| 灵台县| 万安县| 罗田县| 佛山市| 遂溪县| 罗定市| 岳阳市| 衡东县|