[转]使用Struts 2防止表单重复提交
用户重复提交表单在某些场合将会造成非常严重的后果。例如,在使用信用卡进行在线支付的时候,如果服务器的响应速度太慢,用户有可能会多次点击提交按钮,而这可能导致那张信用卡上的金额被消费了多次。因此,重复提交表单会对你的系统带来逻辑影响,必须采取一些措施防止这类情况的发生。
用户重复提交同一个HTML表单的原因有: 一、快速多次点击了提交按钮;二、提交表单后按下浏览器的刷新按钮。
设置Struts 2的预防表单重复提交的功能
Struts 2已经内置了能够防止用户重复提交同一个HTML表单的功能。它的工作原理:让服务器生成一个唯一标记,并在服务器和表单里各保存一份这个标记的副本。此后,在用户提交表单的时候,表单里的标记将随着其他请求参数一起发送到服务器,服务器将对他收到的标记和它留存的标记进行比较。如果两者匹配,这次提交的表单被认为是有效的,服务器将对之做出必要的处理并重新设置一个新标记。随后,提交相同的表单就会失败,因为服务器上的标记已经重置。
Struts 2标签中的token标签,可以用来生成一个独一无二的标记。这个标记必须嵌套在form标签中使用,它会在表单里插入一个隐藏字段并把标记保存到HttpSession对象里。toke标签必须与Token或Token Session拦截器配合使用,两个拦截器都能对token标签进行处理。Token拦截器遇到重复提交表单的情况,会返回一个"invalid.token"结果并加上一个动作级别的错误。Token Session拦截器扩展了Token拦截器并提供了一种更复杂的服务,它采取的做法与Token拦截器不同,它只是阻断了后续的提交,这样用户不提交多少次,就好像只是提交了一次。
示例:使用Token拦截器预防表单重复提交
1. 配置struts.xml文件,声明动作
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="avoidPackage" extends="struts-default">
<action name="avoid" class="struts2.action.AvoidAction">
<interceptor-ref name="token"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
<result name="invalid.token">/error.jsp</result>
<result name="input">/input.jsp</result>
<result name="success">/output.jsp</result>
</action>
</package>
</struts>
此时,需要在动作的声明中,为动作添加token拦截器,因为token拦截器不在defaultStack拦截器栈中,注意,需要将拦截器放在拦截器栈的第一位,这是因为判断表单是否被重复提交的逻辑应该在表单处理前。
2. 创建动作类
public class AvoidAction extends ActionSupport {
private static final long serialVersionUID = 2676453800249807631L;
private String username;
private Date birthday;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String execute()
{
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return SUCCESS;
}
}
这个动作逻辑处理为挂起4秒钟,让我们有机会多次点击提交按钮,测试效果。
3. 创建页面:
input.jsp
<s:form action="avoid">
<s:token></s:token>
<s:textfield name="username" label="Enter your name"></s:textfield>
<s:textfield name="birthday" label="Enter your birthday"></s:textfield>
<s:submit value="submit"></s:submit>
</s:form>
要使用Struts 2的防止表单重复提交功能,需要在form标签中使用token标签,他会产生一个唯一的标识符,与其他参数一起提交到服务器,服务器会根据token标签所产生的标识符判断表单是否为重复提交的表单,这个功能是由Token拦截器完成的。
error.jsp
<body>
do not duplicate submissions form!
</body>
当表单重复提交,Token拦截器会返回一个"invalid.token"结果,结果将页面转到这个页面,提示用户错误信息。
output.jsp
<body>
Your Name : <s:property value="username"/>
<br />
Your Birthday : <s:property value="birthday"/>
</body>
若没有重复提交表单,那么就显示正确的页面。
4. 测试
在浏览器中输入:http://localhost:8081/AvoidDuplicateSubmissions/input.jsp,得到如下界面

连续多次点击"submit"按钮,查看效果

可以看到,token拦截器的设置生效了,他阻止了表单的重复提交,并给出了错误提示
这次我们只点击一次提交(请重新输入URL,或后退到输入页面后刷新一下,这是因为token的标示在提交一次后已被修改,不刷新标示符是不可能与服务器存留的标示符一致的)

可以看到,表单被正确的处理了。
处理表单重复提交的另一个拦截器是 tokenSession,使用该拦截器与使用token拦截器并没有什么差异只需要,引用该拦截器,其他与token拦截器完全一致
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="avoidPackage" extends="struts-default">
<action name="avoid" class="struts2.action.AvoidAction">
<interceptor-ref name="tokenSession"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref> <result name="invalid.token">/error.jsp</result>
<result name="input">/input.jsp</result>
<result name="success">/output.jsp</result>
</action>
</package>
</struts>
[转]使用Struts 2防止表单重复提交的更多相关文章
- 使用Struts 2防止表单重复提交
用户重复提交表单在某些场合将会造成非常严重的后果.例如,在使用信用卡进行在线支付的时候,如果服务器的响应速度太慢,用户有可能会多次点击提交按钮,而这可能导致那张信用卡上的金额被消费了多次.因此,重复提 ...
- JavaWeb使用Session防止表单重复提交
在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交. 1.什么是表单 ...
- struts2视频学习笔记 29-30(Struts 2常用标签,防止表单重复提交)
课时28 Struts 2常用标签解说 property标签 property标签用于输出指定值: <s:set name="name" value="'kk'&q ...
- Struts(二十七):使用token或tokenSession防止表单重复提交
什么是表单重复提交 表单重复提交包括以下几种情况: 前提:不刷新表单页面 1.多次点击“提交”按钮后,重复提交了多次: 2.已经提交成功之后,按“回退”按钮之后,在点击“提交”按钮后,提交成功: 3. ...
- 一脸懵逼学习Struts数据校验以及数据回显,模型驱动,防止表单重复提交的应用。
1:Struts2表单数据校验: (1)前台校验,也称之为客户端校验,主要是通过Javascript编程的方式进行数据的验证. (2)后台校验,也称之为服务器校验,这里指的是使用Struts2通过xm ...
- Struts防止表单重复提交
1.什么是表单重复提交 > 在不刷新表单页面的前提下: >> 多次点击提交按钮 >> 已经提交成功, 按 "回退" 之后 ...
- 12、Struts2表单重复提交
什么是表单重复提交 表单的重复提交: 若刷新表单页面, 再提交表单不算重复提交. 在不刷新表单页面的前提下: 多次点击提交按钮 已经提交成功, 按 "回退" 之后, 再点击 &qu ...
- Struts2防止表单重复提交
1.说明 系统拦截器的应用. 表单重复提交:当使用请求转化进行跳转的时候,存在着表单重复提交的问题. 2.在表单中加入s:token 如果页面加入了struts2的标签,页面的请求必须进入struts ...
- 【转】Struts2解决表单重复提交问题
用户重复提交表单在某些场合将会造成非常严重的后果.例如,在使用信用卡进行在线支付的时候,如果服务器的响应速度太慢,用户有可能会多次点击提交按钮,而这可能导致那张信用卡上的金额被消费了多次.因此,重复提 ...
随机推荐
- Python socket day5
下载文件 程序04,05 服务端在接收到文件名时应该用try来打开文件,不应该用with open来打开否则,如果文件名不存在,用with open 会出错误 客户端要判断服务端发送的数据是否为空,不 ...
- Docker - 容器的 连接 与 退出
概述 连接容器, 退出容器 命令 run exec attach 退出 选项 -i -t -d 1. docker run 概述 docker run 通常用来创建新容器 docker run 的 三 ...
- 每天进步一点点------SOPC的Avalon-MM IP核(二) AVALON总线的IP核定制
简介 NIOS II是一个建立在FPGA上的嵌入式软核处理器,除了可以根据需要任意添加已经提供的外设外,用户还可以通过定制用户逻辑外设和定制用户指令来实现各种应用要求.这节我们就来研究如何定制基于Av ...
- 普通的javaweb项目和用maven管理的javaweb project的目录结构的区别
图一,图二 这种就是单独的建立普通的(也就是没有用maven管理包)javaweb项目的结构目录,这种需要将普通的jar依赖放到lib目录下,之后通过bulid 图一
- 开源分布式系统Druid简谈
介绍 Druid是一个拥有大数据实时查询和分析的高容错.高性能开源分布式系统,旨在快速处理大规模的数据,并能够实现快速查询和分析.尤其是当发生代码部署.机器故障以及其他产品系统遇到宕机等情况时,Dru ...
- BZOJ 3262: 陌上花开 (cdq分治,三维偏序)
#include <iostream> #include <stdio.h> #include <algorithm> using namespace std; c ...
- Jmeter BeanShell笔记
前言:beanshell是支持java语法的,因此当一些复杂的数据结构jmeter处理不了的时候,我们可以借助于java来实现 1,使用beanshell处理JDBC请求返回的值 数据库结构 当JDB ...
- Floyd-Warshall
Description 第一行四个数为n,m,n表示顶点个数,m表示边的条数. 接下来m行,每一行有三个数t1.t2 和t3,表示顶点t1到顶点t2的路程是t3.请注意这些t1->t2是单向的. ...
- 【PAT甲级】1074 Reversing Linked List (25 分)
题意: 输入链表头结点的地址(五位的字符串)和两个正整数N和K(N<=100000,K<=N),接着输入N行数据,每行包括结点的地址,结点的数据和下一个结点的地址.输出每K个结点局部反转的 ...
- 计算机二级-C语言-程序设计题-190112记录-结构体的遍历和结构体的数据的交换处理,文件的操作。
//程序设计题:学生的记录由学号和成绩组成,N名学生的数据已在主函数中放入结构体数组s中,请编写函数fun,它的功能是:把分数低的学生数据放在b所指的数组中,注意:分数最低的学生可能不止一个,函数返回 ...