您的位置:首页 > 理论基础 > 计算机网络

Struts2 防止表单重复提交(转载自:http://blog.csdn.net/hackerain/article/details/6990121)

2014-09-04 11:26 344 查看
防止表单重复提交,这是个很重要的知识点,而且很有用。当用户提交了一个表单,此时,地址栏显示的是处理这个表单的Action的地址,若此时刷新,则会重新发送一次表单数据,即又进行了一次提交,若这个Action是用来处理用户注册的,那么重复提交会再一次向数据库中插入之前已经插入的数据,这显然不是我们想要的。有两种方法,可以防止表单重复提交,一种是用Action的重定向,一种是用Session Token(Session令牌)。

第一种方法,Action处理完用户提交的数据后,重定向到另一个Action或是一个页面,使用户提交后,所停留的位置,不是当前处理数据的Action,这样用户再刷新时,就不会再次执行这个Action了,就会避免表单重复提交的问题了。

第二种方法,是一种很经典的处理这个问题的机制。这种方法是在用户要提交的表单中,加入一个<s:token>标签,这样,当浏览器第一次访问这个带有<s:token>标签的页面时,在服务器中,解析<s:token>标签的类(TokenTag.class),会生成一个随机的字符串(这个字符串,查看网页的源代码可以看到),并且发送给客户端的浏览器,同时,在服务器中,会把这个随机字符串保存到用户的session对象中。当第一次提交表单时,在服务器中,会比较客户端和服务器中分别保存的这个随机字符串,因为是第一次提交,所以这两个字符串相等,然后进行正常的业务处理。第一次提交后,在服务器中的session中保存的这个随机字符串,会改变为其他的随机值,注意,这是很重要的一步!此时,地址栏停留在处理用户提交数据的Action中,客户端中保存的随机字符串没有改变,若是刷新页面,即重复提交,服务器再进行两个字符串的比较,会不相等,就会跳转到name为invalid.token的结果页面中,这样就会防止表单重复提交了。

第一种方法的举例,在上一篇博客中,这里就不再列出了,这里主要举例说明一下session token的机制:

[html] view
plaincopy

Login.jsp:

<s:form action="/test/token" theme="simple">

username:<s:textfield name="username"></s:textfield><br>

password:<s:password name="password"></s:password><br>

<s:submit value="submit"></s:submit>

<s:token></s:token><!--一定要有这个标签-->

</s:form>

[html] view
plaincopy

struts.xml:

<action name="token" class="com.suo.actions.TokenAction">

<result name="success">/WEB-INF/result/LoginResult.jsp</result>

<result name="invalid.token">/WEB-INF/result/TokenFailed.jsp</result>

<!-- 若重复提交,则会跳转到这个页面,注意这里result的名字,一定要是invalid.token -->

<interceptor-ref name="token"></interceptor-ref>

<interceptor-ref name="defaultStack"></interceptor-ref>

<!-- 这里一定要有这两个拦截器 -->
////<interceptor-ref>两个可以放在<result>上面

</action>

[java] view
plaincopy

TokenAction.java:

package com.suo.actions;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpSession;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class TokenAction extends ActionSupport {

private String username;

private String password;

public String getUsername() {

return username;

}

public void setUsername(String username) {

this.username = username;

}

public String getPassword() {

return password;

}

public void setPassword(String password) {

this.password = password;

}

public String execute()

{

return SUCCESS;

}

}

结果页面就不写了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: