使用session防止表单进行重复提交
我们都知道可以通过js的方法来实现防止表单重复提交,但是js只适用于“在网络延迟的情况下让用户有时间点击多次submit按钮导致表单重复提交” 的情况下进行操作,
那如果碰到“表单提交后用户点击【刷新】按钮导致表单重复提交”和“用户提交表单后,点击浏览器的【后退】按钮回退到表单页面后进行再次提交”的场景下JS就显得心有余而力不足了,这个时候我们可以通过java当中生成token验证token来实现防止表单提交;
先看一下我的项目结构:

我们用到的只有这四个页面,其他的可以忽略
首先先来看一下创建token的servlet,tokenDemo.java:
package session; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException; @WebServlet(name = "TokenDemo",urlPatterns = {"/session/TokenDemo"})
public class TokenDemo extends HttpServlet {
private static final long serialVersionUID = -884689940866074733L;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String token = TokenProccessor .getInstance().makeToken();//创建令牌
// System.out.print("生成的令牌token是"+token);
request.getSession().setAttribute("token",token); //存到session里面
request.getRequestDispatcher("/token.jsp").forward(request,response);
}
}
这里面有一个生成token的类,叫做TokenProccessor,接下来我们看看token是怎么生成的,
TokenProccessor .java:
package session; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random; import sun.misc.BASE64Encoder; public class TokenProccessor {
private TokenProccessor() {} ;
private static final TokenProccessor instance = new TokenProccessor(); public static TokenProccessor getInstance() {
return instance;
} //生成token
public String makeToken(){
String token = (System.currentTimeMillis() + new Random().nextInt(999999999)) + "";
try{
MessageDigest md = MessageDigest.getInstance("md5");
byte md5[] = md.digest(token.getBytes());
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(md5);
}catch(NoSuchAlgorithmException e){
throw new RuntimeException(e);
}
} }
好,我们现在有了token,我们可以在页面上去使用它:token.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>token</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/session/ResultToken" method="post">
<%--使用隐藏存储生成token--%> <input type="hidden" name="token" value="${token}">
用户名:<input type="text" name="username">
<input type="submit" value="提交"> </form> </body>
</html>
我们接下来应该干嘛呢,对,当然是要进行表单的验证啦,resultToken.java:
package session; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException; @WebServlet(name = "ResultToken", urlPatterns = {"/session/ResultToken"})
public class ResultToken extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=utf-8");
boolean b = isRepeatSubmit(request); //判断用户是否重复提交;
if (b == true) {
response.getWriter().println("请不要重复提交");
return;
}
request.getSession().removeAttribute("token");
response.getWriter().println("处理用户提交请求");
} /***
* 判断用户提交上来的token和服务器生成的token是否一致
* true:重复提交了
*false:没有重复提交
* */
private boolean isRepeatSubmit(HttpServletRequest request) {
String client_token = request.getParameter("token");
//如果用户提交的没有token,那么用户则是重复提交了表单
if (client_token == null) {
return true;
}
//取出session中的token
String server_token = (String) request.getSession().getAttribute("token");
//如果哦用户的session里面不存在Token,则用户重复提交了表单
if (server_token.equals(client_token)) {
return true;
}
return false;
}
}
ok,记得写完servlet的时候必须要去web.xml配置一下,不然取不到路径。所有的登录都需要来验证token。
使用session防止表单进行重复提交的更多相关文章
- Session机制三(表单的重复提交)
1.表单的重复提交的情况 在表单提交到一个servlet,而servlet又通过请求转发的方式响应了一个JSP页面,这个时候地址栏还保留这servlet的那个路径,在响应页面点击刷新. 在响应页面没有 ...
- php-- 避免表单的重复提交
用户提交表单时可能因为网速的原因,或者网页被恶意刷新,致使同一条记录重复插入到数据库中,这是一个比较棘手的问题.我们可以从客户端和服务器端一起着手,设法避免同一表单的重复提交. 1.使用客户端脚本 提 ...
- Spring MVC表单防重复提交
利用Spring MVC的过滤器及token传递验证来实现表单防重复提交. 创建注解 @Target(ElementType.METHOD) @Retention(RetentionPolicy.RU ...
- HttpSession解决表单的重复提交
1). 重复提交的情况: ①. 在表单提交到一个 Servlet, 而 Servlet 又通过请求转发的方式响应一个 JSP(HTML) 页面, 此时地址栏还保留着 Serlvet 的那个路径, 在响 ...
- Struts2 - 表单的重复提交问题
用户重复提交表单在某些场合将会造成非常严重的后果.例如,在使用信用卡进行在线支付的时候,如果服务器的响应速度太慢,用户有可能会多次点击提交按钮,而这可能导致那张信用卡上的金额被消费了多次.因此,重复提 ...
- 使用aop注解实现表单防重复提交功能
原文:https://www.cnblogs.com/manliu/articles/5983888.html 1.这里采用的方法是:使用get请求进入表单页面时,后台会生成一个tokrn_flag分 ...
- HttpSession之表单的重复提交 & 验证码
如果采用 HttpServletResponse.sendRedirct() 方法将客户端重定向到成功页面,将不会出现重复提交问题 1.表单的重复提交 1). 重复提交的情况: ①. 在表单提交到一个 ...
- struts2 文件的上传下载 表单的重复提交 自定义拦截器
文件上传中表单的准备 要想使用 HTML 表单上传一个或多个文件 须把 HTML 表单的 enctype 属性设置为 multipart/form-data 须把 HTML 表单的method 属性设 ...
- php中如何防止表单的重复提交
在php中如何防止表单的重复提交?其实也有几种解决方法. 下面小编就为大家介绍一下吧.需要的朋友可以过来参考下 代码: <?php /* * php中如何防止表单的重复提交 * by www.j ...
随机推荐
- Axiom3D:Ogre射线与点,线,面相交,鼠标操作3维空间.
在第一篇网络分解成点,线,面.第二篇分别点以球形,线以圆柱,面分别以MergerBatch整合批次显示.因为整合批次显示后,相应的点,线,面不能以Ogre本身的射线来选取,因为整合后,以点举例,多个点 ...
- 无法定位序数 12384 于动态链接库 mfc90.dll
场景: 运行 vs2008 编译生成的一个 exe 错误: 无法定位序数 12384 于动态链接库 mfc90.dll 原因: 缺少vc++ 2008 运行库. vcredist 全称Microsof ...
- Python——hashlib
该模块实现了诸多安全哈希和消息摘要算法的通用接口,包括 FIPS 安全哈希算法: SHA1, SHA224, SHA256, SHA384 和 SHA512 算法(在 FIPS 180-2 中定义), ...
- poj1276
题目链接:http://poj.org/problem? id=1276 Cash Machine Time Limit: 1000MS Memory Limit: 10000K Total Su ...
- pyremotevbox 用法
>>> import pyremotevbox.vbox as vbox >>> host = vbox.VirtualBoxHost(host='10.0.2.2 ...
- Linux网卡eth0变成eth1修改方法
由于换了主板,集成网卡mac地址变了,70-persistent-net.rules中仍然保留了老网卡的内容,新网卡则被识别为eth1. 将表示老网卡的行注释掉,然后将表示新网卡的行中eth1改成et ...
- Gateway/Worker模型 数据库使用示例
From: http://www.bubuko.com/infodetail-777418.html 1.数据库配置Applications/XXX/Config/Db.php <?php na ...
- [转]Apache 监听端口失败,selinux惹的祸
原文在此 CentOS 下启动Httpd 失败,报 (13)Permission denied: make_sock: could not bind to address [::]:8000 因为 小 ...
- asp.net mvc maproute定义可变数量的自定义片断变量
有时候我们定义了如{controller}/{action}/{id}之类的路由规则,但是后面还可能跟上一堆可能会有可能不会有,但是路由规则是一样的,如{controller}/{action}/{i ...
- Java编程思想学习笔记——初始化与清理
初始化 构造器保证初始化 构造器采用与类相同的名称. 默认构造器(default constructor):不接受任何参数的构造器,也叫无参构造器. 构造器也能带有形式参数,就能在初始化对象时提供实际 ...