我的漫漫程序之旅

          專注于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 | 訂單
          主站蜘蛛池模板: 阳信县| 沙洋县| 若羌县| 临汾市| 沿河| 灌云县| 噶尔县| 遵义市| 太仆寺旗| 秦安县| 德惠市| 莲花县| 崇仁县| 陈巴尔虎旗| 北川| 呼伦贝尔市| 丰城市| 枞阳县| 霍林郭勒市| 五原县| 兰坪| 清新县| 长宁县| 青浦区| 阿坝| 汕尾市| 大足县| 通化市| 榆中县| 宁都县| 临泽县| 邯郸县| 新丰县| 吕梁市| 建德市| 射阳县| 漠河县| 田东县| 岳池县| 安岳县| 广南县|