Struts2 Token防止重复提交

在用户注册的时候,当我们提交数据到后台之后,再点击浏览器的刷新,会重复再把表单数据提交一次,这样导致数据重复插入。如何解决表单重复提交呢?答案是,使用Struts2的Token机制!

1 Struts2的Token实现原理

所谓的Token,中文译名“令牌”。顾名思义,就是使用一种验证,验证对了,就让你继续访问action,验证错了,直接把你拦截住,交给指定的页面。验证的关键步骤就是token拦截器的原理:当浏览器访问一个带有<s:token></s:token>标签的页面时,服务器生成一个随机数,把这个随机数放入session中,也放入表单中隐藏的token属性中。显然,此时这两个随机数是相等的。而后,当你向服务器提交表单时,表单中隐藏的token属性也会传给服务器。此时如果访问的的action使用了token的拦截器(即上面配置的),那么服务器会从session中得到刚才的随机数,将其和表单的token属性比较,看两者是否相同。如果相等,表示此次访问不是重复提交,无需拦截,清空session中的随机数,接着正常访问action。如果不相等,则直接拦截,不会继续访问action,直接跳到<result name="invalid.token">指定的页面,并且session中的随机数不变。

为什么验证通过后要清空session中的随机数值呢?因为重复提交必然有一个特性:它的token属性是上一个,因此清空session中的随机数后就保证了不相等。想要通过验证则必须重新加载带有<token>标签的jsp。

1)Token生成原理图

2)Token拦截原理图

2 实现Token防止表单重复提交

2.1 设计一个注册表单

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>一点教程-struts2的令牌机制</title>
  </head>
  
  <body>
  <h3>防止重复提交</h3>
  <form action="demo1.action" method="post">
  	<s:token/>
  	用户名:<input type="text" name="name"/><br/>
  	密码:<input type="password" name="password"/><br/>
  	手机:<input type="text" name="phone"/><br/>
  	邮箱:<input type="text" name="email"/><br/>
  	<input type="submit" value="注册"/>
  </form>
  </body>
</html>

2.2 编写Action

package com.yiidian.action;
import com.opensymphony.xwork2.ActionSupport;
/**
 * 防止表单重复提交
 * @author  一点教程(yiidian.com)
 */
public class Demo1Action extends ActionSupport{
	@Override
	public String execute() throws Exception {
		System.out.println("执行注册操作");
		return SUCCESS;
	}
}

2.3 配置Token拦截器 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
	"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
	<package name="base" extends="struts-default" namespace="/">
		<action name="demo1" class="com.yiidian.action.Demo1Action">
			<interceptor-ref name="token"/>
			<result>/succ.jsp</result>
			<!-- 当出现重复提交,则跳转到invalid.token -->
			<result name="invalid.token">/index.jsp</result>
		</action>
	</package>	
</struts>

注意: invalid.token这个视图名称是Struts2判断JSP页面生成的Token ID和拦截器存储的Token ID不相等的时候,跳转到该视图定义的页面。

2.4 运行测试

1)第一次表单提交

2)通过点击刷新按钮,实现表单重复提交

3)点击"继续"后,回到注册页面,证明拦截成功啦

 

源码下载:https://pan.baidu.com/s/1jjQvID6j2T7tSE9c8kjJOA

热门文章

优秀文章