使用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 ...
随机推荐
- 产品需求文档 PRD
第一轮: 1,文档使用方:UI设计师 2.内容: 根据战略层定义出来产品功能范围, 说明此产品的目的,方便UI设计人员更好的理解产品 产品基本流程 详细 ...
- oracle 中execute immediate
简单来说 就是你一个存储过程当中 创建了一个表 table_a 然后要用insert into将其他的数据插入到这个table_a当中,但是因为你在创建过程的时候 table_a还不存在,过程就会显示 ...
- (笔记)Mysql命令mysql:连接Mysql数据库
mysql命令用户连接数据库. mysql命令格式: mysql -h主机地址 -u用户名 -p用户密码 1) 连接到本机上的MYSQL首先打开DOS窗口,然后进入目录mysql\bin,再键入命令m ...
- Cg入门10:Vertex Shader - 几何变换 —MVP矩阵变换
Unity内建矩阵类型: M:世界矩阵 V:摄像机矩阵 P:投影矩阵 T :矩阵的转置 IT : 转置的的逆 _Object2World: 模型到世界矩阵 _World2Object:世界到模型矩阵 ...
- C#常用数据类型间的转换
数据类型有很多种,数据类型间的转换也是有很多的方法,如果不细心整理的话等到用的时候再查就会显得很浪费时间,所以决心整理出这篇博文.主要是讲解常用数据类型之间的转换方法以及常见数据类型所占字节数. 字节 ...
- iOS : 用 InterfaceBuilder 开始一个项目
1.创建一个 xib 文件 : Main_iPhone.xib 更改 File's Owner 的 Class 为 UIApplication; 添加 1 个 Window .1 个 Object . ...
- Spring定时器的两种实现方式
有两种流行Spring定时器配置:Java的Timer类和OpenSymphony的Quartz. 1.Java Timer定时 首先继承java.util.TimerTask类实现run方法 imp ...
- 利用Android NDK编译lapack
最近有这方面的需要,但是在网上查了一下,几乎没有讲这个的.后来发现了外国某个大牛在github上的project.拉下来自己编译了一下竟然通过了,记录如下: 1.从https://github.com ...
- asp.net单击头模板中的checkbox,实现datalist中所有chebox的全选和取消
转载时请以超链接形式标明文章原始出处和作者信息及本声明http://blueseach.blogbus.com/logs/31281126.html 使用C#和javascript都可以实现,第二种更 ...
- Struts2+Hibernate+Spring(SSH)三大框架整合jar包
Struts2 + Spring3 + Hibernate3 框架整合 1. 每个框架使用 (开发环境搭建 )* 表现层框架 struts2 1) jar包导入: apps/struts2_blank ...