athrunwang

          紀元
          數據加載中……
          使用Struts 2防止表單重復提交

            用戶重復提交表單在某些場合將會造成非常嚴重的后果。例如,在使用信用卡進行在線支付的時候,如果服務器的響應速度太慢,用戶有可能會多次點擊提交按鈕,而這可能導致那張信用卡上的金額被消費了多次。因此,重復提交表單會對你的系統帶來邏輯影響,必須采取一些措施防止這類情況的發生。

            用戶重復提交同一個HTML表單的原因有: 一、快速多次點擊了提交按鈕;二、提交表單后按下瀏覽器的刷新按鈕。


          設置Struts 2的預防表單重復提交的功能 

                Struts 2已經內置了能夠防止用戶重復提交同一個HTML表單的功能。它的工作原理:讓服務器生成一個唯一標記,并在服務器和表單里各保存一份這個標記的副本。此后,在用戶提交表單的時候,表單里的標記將隨著其他請求參數一起發送到服務器,服務器將對他收到的標記和它留存的標記進行比較。如果兩者匹配,這次提交的表單被認為是有效的,服務器將對之做出必要的處理并重新設置一個新標記。隨后,提交相同的表單就會失敗,因為服務器上的標記已經重置。 

            Struts 2標簽中的token標簽,可以用來生成一個獨一無二的標記。這個標記必須嵌套在form標簽中使用,它會在表單里插入一個隱藏字段并把標記保存到HttpSession對象里。toke標簽必須與Token或Token Session攔截器配合使用,兩個攔截器都能對token標簽進行處理。Token攔截器遇到重復提交表單的情況,會返回一個"invalid.token"結果并加上一個動作級別的錯誤。Token Session攔截器擴展了Token攔截器并提供了一種更復雜的服務,它采取的做法與Token攔截器不同,它只是阻斷了后續的提交,這樣用戶不提交多少次,就好像只是提交了一次。 


          示例:使用Token攔截器預防表單重復提交

          1.  配置struts.xml文件,聲明動作

          <?xml version="1.0" encoding="UTF-8" ?>
          <!DOCTYPE struts PUBLIC
          "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
          "http://struts.apache.org/dtds/struts-2.0.dtd"
          >
          <struts>
          <package name="avoidPackage" extends="struts-default">
          <action name="avoid" class="struts2.action.AvoidAction">
          <interceptor-ref name="token"></interceptor-ref>
          <interceptor-ref name="defaultStack"></interceptor-ref>

          <result name="invalid.token">/error.jsp</result>
          <result name="input">/input.jsp</result>
          <result name="success">/output.jsp</result>
          </action>
          </package>
          </struts>

          此時,需要在動作的聲明中,為動作添加token攔截器,因為token攔截器不在defaultStack攔截器棧中,注意,需要將攔截器放在攔截器棧的第一位,這是因為判斷表單是否被重復提交的邏輯應該在表單處理前。

          2. 創建動作類

          public class AvoidAction extends ActionSupport {
          private static final long serialVersionUID = 2676453800249807631L;

          private String username;
          private Date birthday;

          public String getUsername() {
          return username;
          }
          public void setUsername(String username) {
          this.username = username;
          }
          public Date getBirthday() {
          return birthday;
          }
          public void setBirthday(Date birthday) {
          this.birthday = birthday;
          }

          @Override
          public String execute()
          {
          try {
          Thread.sleep(4000);
          } catch (InterruptedException e) {
          e.printStackTrace();
          }

          return SUCCESS;
          }

          }

          這個動作邏輯處理為掛起4秒鐘,讓我們有機會多次點擊提交按鈕,測試效果。

          3. 創建頁面:

          input.jsp

          <s:form action="avoid">
          <s:token></s:token>
          <s:textfield name="username" label="Enter your name"></s:textfield>
          <s:textfield name="birthday" label="Enter your birthday"></s:textfield>
          <s:submit value="submit"></s:submit>
          </s:form>

          要使用Struts 2的防止表單重復提交功能,需要在form標簽中使用token標簽,他會產生一個唯一的標識符,與其他參數一起提交到服務器,服務器會根據token標簽所產生的標識符判斷表單是否為重復提交的表單,這個功能是由Token攔截器完成的。

          error.jsp

          <body>
          do not duplicate submissions form!
          </body>

          當表單重復提交,Token攔截器會返回一個"invalid.token"結果,結果將頁面轉到這個頁面,提示用戶錯誤信息。

          output.jsp

          <body>
          Your Name : <s:property value="username"/>
          <br />
          Your Birthday : <s:property value="birthday"/>
          </body>

          若沒有重復提交表單,那么就顯示正確的頁面。

          4. 測試

          在瀏覽器中輸入:http://localhost:8081/AvoidDuplicateSubmissions/input.jsp,得到如下界面

          連續多次點擊"submit"按鈕,查看效果

          可以看到,token攔截器的設置生效了,他阻止了表單的重復提交,并給出了錯誤提示

          這次我們只點擊一次提交(請重新輸入URL,或后退到輸入頁面后刷新一下,這是因為token的標示在提交一次后已被修改,不刷新標示符是不可能與服務器存留的標示符一致的)

          可以看到,表單被正確的處理了。

          處理表單重復提交的另一個攔截器是 tokenSession,使用該攔截器與使用token攔截器并沒有什么差異只需要,引用該攔截器,其他與token攔截器完全一致

          <?xml version="1.0" encoding="UTF-8" ?>
          <!DOCTYPE struts PUBLIC
          "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
          "http://struts.apache.org/dtds/struts-2.0.dtd"
          >
          <struts>
          <package name="avoidPackage" extends="struts-default">
          <action name="avoid" class="struts2.action.AvoidAction">
          <interceptor-ref name="tokenSession"></interceptor-ref>
          <interceptor-ref name="defaultStack"></interceptor-ref>

          <result name="invalid.token">/error.jsp</result>
          <result name="input">/input.jsp</result>
          <result name="success">/output.jsp</result>
          </action>
          </package>
          </struts>

          posted on 2011-11-18 10:43 AthrunWang 閱讀(159) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 安龙县| 大兴区| 彰化市| 普格县| 方正县| 安宁市| 定襄县| 襄垣县| 临高县| 石屏县| 芦山县| 瓮安县| 中卫市| 区。| 屏东县| 清涧县| 民勤县| 大埔区| 忻城县| 武汉市| 扎赉特旗| 新安县| 海林市| 桃园市| 晴隆县| 周宁县| 阿勒泰市| 永胜县| 二连浩特市| 浦东新区| 亚东县| 报价| 通许县| 泽库县| 涞水县| 广州市| 绿春县| 沙湾县| 柏乡县| 大丰市| 长兴县|