Struts2 表單重複提交問題
1.什麼是重複提交
在不重新整理表單頁面的情況下
- 》多次點選提交按鈕
- 》已經提交成功了,按“回退”之後,再點選"提交按鈕"
- 》在控制器相應頁面的形式為轉發的情況下,已經提交成功,然後點選重新整理或者f5
注意:
- 》若重新整理表單頁面,再提交表單就不是重複提交
- 》若使用redirect的相應型別,已經提交成功之後,再點選"重新整理",不算是重複提交
表單重複提交的危害
-
增加伺服器的負擔
-
導致程式錯誤
解決的方式:Token攔截器或者TokenSession攔截
一、在s:form中新增一個子標籤s:token
- 這個子標籤會生成一個隱藏域
- 在session新增一個屬性值
隱藏域和session的屬性值一致就提交成功
二 使用Token或TokenSession攔截器
》這兩個攔截器均不在預設的攔截器棧中,所以需要手工配置一下
》若使用Token攔截器,則需要配置token.valid的result
》若使用TokenStack攔截器,則不需要為他配置任何其他的result
三、Token vs TokenStack
》都是解決表單重複提交問題的
》使用token攔截器,則需要配置一個token.valid的result
》若使用TokenSession攔截器,則還會響應那個目標頁面,但是不會執行tockenSession之後的攔截器,跟什麼也沒有發生一樣
四、可以使用s:actionerror標籤來顯示重複提交的錯誤訊息
該錯誤訊息可以在國際資原始檔中覆蓋,該訊息可以在struts-messages.properties檔案中找到
demo如下
jsp表單頁面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>表單重複提交的問題</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> </head> <body> <s:form action="texttoken"> <s:token></s:token> <s:textfield label="name" name="username"></s:textfield> <s:submit></s:submit> </s:form> </body> </html>
struts.xml
<action name="texttoken" class="cn.com.app.TextToken">
<interceptor-ref name="token"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
<result>/success.jsp</result>
<result name="invalid.token">/error.jsp</result>
</action>
Action類
package cn.com.app;
import com.opensymphony.xwork2.ActionSupport;
public class TextToken extends ActionSupport {
private String username;
public void setUsername(String username) {
this.username = username;
}
public String getUsername() {
return username;
}
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
System.out.println(username);
return super.execute();
}
}
錯誤資訊頁面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>錯誤資訊</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>
<body>
<s:actionerror/>
</body>
</html>
當我們在前臺頁上輸入一個名字的時候,點選提交到了提交成功的頁面,點選重新整理,就會出現報錯頁面、顯示錯誤資訊
如果使用的是tokenSession攔截器的話,就如下操作就可以了
<action name="texttoken" class="cn.com.app.TextToken">
<interceptor-ref name="tokenSession"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
<result>/success.jsp</result>
<!-- <result name="invalid.token">/error.jsp</result> -->
</action>
頁面也不會列印錯誤資訊,就跟什麼也沒有發生一樣