什么是重复提交?
当我们在网站上买卖交易中如果此时的网速不给力,你是不是有一种多次点击的冲动,如果你要买飞机票,如果没有防止重复提交,你是不是点了几下就买了几张飞机票呢?如果是一些大的项目呢?这个责任终归会归属于程序员的头上,所以防止重复提交表单,是比较使用的技术,
是不是防止重复提交很难很麻烦呢?
不是,只需要几个简单的步骤就可以完成了。下面就跟着小奎来学习吧,我们先做一个比较简单的实例证明一下效果。
(1)首先:创建一个index.jsp的页面和success.jsp页面
<%@ page language="java" import="java.util.*" pageEncoding="GBK"%> <%@ taglib uri="/struts-tags" prefix="s"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>提交</title> </head> <body> <h1 style="color: red"><s:actionerror /></h1><br /> <s:form action="token.action"> <s:token /><%--必须加上这句话 token:令牌 --%> <s:textfield name="orderid" label="订单" /> <s:submit /> </s:form> </body> </html>
(2) 写一个TokenAction
import com.opensymphony.xwork2.ActionSupport; public class TokenAction extends ActionSupport { private String orderid; // 订单的Id // 省略get和set方法 @Override public String execute() throws Exception { System.out.println("正在提交编号为:" + orderid + " 的订单....."); Thread.sleep(6000); // 延时 System.out.println("睡醒了"); return super.execute(); } }
(3)配置struts.xml文件:
说明:在Struts-default中没有包含这个Token的拦截器,但是默认拦截器并未加载它,所以我们在Struts.xml中需要自己来定义加载
如果不添加上面红线部分就会报找不到这个返回invalid.token错误
运行结果
这个时候我们发现它虽然可以防止了重复提交表单,但是依然没有我们预期的效果6000毫秒后跳转到success.jsp页面,这是为什么呢?
假设我在8点钟提交一次,9点钟提交一次,10点钟时候执行提交,这时候8点钟提交的表单信息和8点钟时候随着提交的自动隐藏域信息将会进行比较是否相同,假设9点钟没有重复提交,则隐藏在session的隐藏域信息不变,就会提交一次execute方法,如果我们在9点提交一次,则9点中提交的session值和8点钟提交的信息不同,不相同就将他们定位到invoid.token的result防止重复提交,所以不难理解会进入struts.xml文件定位的result而不是success页面。
那么话说回来,有没有解决方法呢?
有的
Ok 小例子完毕。