(1)       避免表单的重复提交的方式:

Ø  采用HttpServletRequest.sendRedirect()方法将客户端重定向到成功页面。

Ø  在客户端通过JavaScript实现;

Ø  在服务端编写代码实现。

(2)       在服务器端避免表单重复提交,通常是采用同步令牌的方式来实现,其基本的原理如下:

(1)用户访问包含表单的页面,服务器端在这次会话中,创建一个Session对象,并产生一个令牌值,将这个令牌值作为隐藏输入域(<input>元素的type属性为hidden)的值随表单一起发送到客户端,同时将令牌值保存到Session中。

(2)用户提交页面,服务器端首先判断请求参数中的令牌值和Session中保存的令牌值是否相等,如果相等,则淸除Session中的令牌值,然后执行数据处理操作。如果不相等,则提示用户己经提交过了表单,同时产生一个新的令牌值,保存到Session中。当用户重新访问提交数据页面时,将新产生的令牌值作为隐藏输入域的值。

(3)       Struts 2的实现方式:

1)需要在表单中使用<s:token>标签,并置定一个令牌的名称。例如:<s:token name=”user.token” />

2)为Action类配置应用TokenInterceptor或者TokenSessionStoreInterceptor拦截器,这两个拦截器已经在struts-default.xml中定义,但没有包含在default拦截器栈中.

 

范例:避免重复提交表单

 

TokenAction.java:

 

 

 
  
  1. import com.opensymphony.xwork2.ActionSupport; 
  2. import com.opensymphony.xwork2.ModelDriven; 
  3. public class TokenAction extends ActionSupport implements ModelDriven<User> { 
  4.     private static final long serialVersionUID = 7502909137522615270L; 
  5.     private User user=new User(); 
  6.     @Override 
  7.     public User getModel() { 
  8.         return user; 
  9.     } 
  10.     @Override 
  11.     public String execute() throws Exception { 
  12.         if ("qiang".equalsIgnoreCase(user.getName())&&"1234".equals(user.getPassword())) { 
  13.             return SUCCESS; 
  14.         } else { 
  15.             return ERROR; 
  16.         } 
  17.     } 

 

User.java:

 

 

 
  
  1. public class User { 
  2.     private String name; 
  3.     private String password; 
  4.     //省略getter与setter方法 

 

token_login.jsp:

 
  
  1. <body> 
  2.     <s:form action="token"
  3.         <s:textfield name="name" label="姓名"></s:textfield><br> 
  4.         <s:password name="password" label="密码"></s:password><br> 
  5.         <s:token></s:token><br> 
  6.         <s:submit value="提交"></s:submit><br> 
  7.     </s:form> 
  8.   </body> 

struts.xml

 

 
  
  1. <package name="token" extends="struts-default"> 
  2.         <action name="token" class="com.mzsx.token.TokenAction"> 
  3.             <result name="success">/s15/success.jsp</result> 
  4.             <result name="invalid.token">/s15/error.jsp</result> 
  5.             <interceptor-ref name="token"></interceptor-ref> 
  6.             <interceptor-ref name="defaultStack"></interceptor-ref> 
  7.         </action> 
  8.     </package>