struts2防止重複提交

用戶重複提交表單在某些場合將會形成很是嚴重的後果。例如,在使用信用卡進行在線支付的時候,若是服務器的響應速度太慢,用戶有可能會屢次點擊提交按鈕,而這可能致使那張信用卡上的金額被消費了屢次。所以,重複提交表單會對你的系統帶來邏輯影響,必須採起一些措施防止這類狀況的發生。apache

  用戶重複提交同一個HTML表單的緣由有: 1、快速屢次點擊了提交按鈕;2、提交表單後按下瀏覽器的刷新按鈕。瀏覽器


設置Struts 2的預防表單重複提交的功能 服務器

      Struts 2已經內置了可以防止用戶重複提交同一個HTML表單的功能。它的工做原理:讓服務器生成一個惟一標記,並在服務器和表單裏各保存一份這個標記的副本。此後,在用戶提交表單的時候,表單裏的標記將隨着其餘請求參數一塊兒發送到服務器,服務器將對他收到的標記和它留存的標記進行比較。若是二者匹配,此次提交的表單被認爲是有效的,服務器將對之作出必要的處理並從新設置一個新標記。隨後,提交相同的表單就會失敗,由於服務器上的標記已經重置。 jsp

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


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

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

複製代碼

<?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攔截器棧中,注意,須要將攔截器放在攔截器棧的第一位,這是由於判斷表單是否被重複提交的邏輯應該在表單處理前。spa

2. 建立動做類orm

複製代碼

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秒鐘,讓咱們有機會屢次點擊提交按鈕,測試效果。xml

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>
相關文章
相關標籤/搜索