【1】首先說明什麼是表單的重複送出
:-)
在不重新整理表單頁面的前提下:1.多次點選送出按鈕;
———————-
2.已經送出成功,按“回退”之後,再點選送出;
——————-—
3.在控制器響應頁面的形式為轉發情況下,若已經送出成功,然後點選重新整理(F5);
若重新整理表單頁面,再送出表單不算重複送出;
- - - 和在浏覽器新開一個頁面送出表單性質相似
若使用的是redirect的響應類型,已經送出成功後,再點選重新整理,不是表單的重複送出!!
【2】Struts2解決表單重複送出
I. 在JSP頁面 s:form 中添加 s:token 子标簽
> 生成一個隐藏域
> 在 session 添加一個屬性值
> 隐藏域的值和 session 的屬性值是一緻的.
<s:form action="testToken" method="post">
<s:token></s:token>
<s:textfield name="username" label="Username"></s:textfield>
<s:submit></s:submit>
</s:form>
II. 使用 Token 或 TokenSession 攔截器.
> 這兩個攔截器均不在預設的攔截器棧中, 是以需要手工配置一下
> 若使用 Token 攔截器, 則需要配置一個 token.valid 的 result
> 若使用 TokenSession 攔截器, 則不需要配置任何其它的 result
<action name="testToken" class="com.web.token.TokenAction">
<interceptor-ref name="token"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
<result >/success.jsp</result>
<result name="invalid.token">/token-error.jsp</result>
</action>
【3】運作原理

簡要說明:
s:token标簽配合token攔截器使用,會在頁面生成隐藏域,并将其屬性值放入session中。
Token攔截器會在請求發出後,取出隐藏域和session中的值進行比較。若一緻,則移除session裡面值,執行後續攔截器;若不一緻,傳回invalid.token….
- JSP頁面生成隐藏域如下:
【4】Token VS TokenSession
都是解決表單重複送出問題的
使用 token 攔截器會轉到 token.valid 這個 result
使用 tokenSession 攔截器則還會響應那個目标頁面, 但不會執行 tokenSession 的後續攔截器. 就像什麼都沒發生過一樣!
【5】Token消息提示
該消息提示位于對象棧中:
可以使用
标簽來顯示重複送出的錯誤消息.
<s:actionerror/>
- 該消息提示内容可以在 struts-messages.properties 檔案中找到
struts.messages.invalid.token=The form has already been processed or no token was supplied, please try again.
可以對其進行國際化!
- 效果如下:
-
内容如下:<s:debug/>