使用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 ...
随机推荐
- (笔记)Linux下的准确延时,#include <linux/delay.h>调用出错
在编写应用层程序时,有时需要延时一下,这个时候该怎么办呢? 在内核代码中,我们经常会看到这样的头文件使用#include <linux/delay.h>,心想着直接调用这个就可以了吧!可是 ...
- (转)DSound开发常用的几个结构
WAVEFORMATEX WAVEFORMATEX { WORD wFormatTag; WORD nChannels; DWORD nSamplesPerSec; DWORD nAvgBytesPe ...
- C# 线程池执行操作例子
public partial class Form1 : Form { CountdownEvent hander = ); public static object lock_action = ne ...
- Git 基础 - 远程仓库的使用
远程仓库的使用 要参与任何一个 Git 项目的协作,必须要了解该如何管理远程仓库.远程仓库是指托管在网络上的项目仓库,可能会有好多个,其中有些你只能读,另外有些可以写.同他人协作开发某个项目时,需要管 ...
- unity3d Matrix4x4列为主序
unity3d的矩阵一直用,但是之前都是测试着用的,效果虽然正确,但是一直没搞清楚它是行矩阵还是列矩阵 今天测试了下 Matrix4x4 mat4 = Matrix4x4.Perspective(30 ...
- 在swift中使用线程休眠
C#和php都有sleep让线程休眠指定时间后再继续执行后面的代码,swift中应该如何呢?首先,找一下objective-c版本是怎么做的 [self performSelector:@select ...
- 如何在xml中设置textview不可见
可见(visible)XML文件:android:visibility="visible"Java代码:view.setVisibility(View.VISIBLE);不可见(i ...
- .net的session详解 存储模式 存到数据库中 使用范围与大小限制 生命周期
Session又称为会话状态,是Web系统中最常用的状态,用于维护和当前浏览器实例相关的一些信息.举个例子来说,我们可以把已登录用户的用户名放在Session中,这样就能通过判断Session中的某个 ...
- ABBYY FineReader 12没你想得那么简单
你是否觉得自己对ABBYY FineReader 12已经了如指掌了?也许你会认为它不过就是一款OCR文字识别软件,能够快速方便地将扫描纸质文档.PDF文件或者数码相机的图像转换为可编辑.可搜索的格式 ...
- jsp新建项目
1.在原有项目的基础上新建一个文件夹 在文件夹内新建一个jsp文件 取名 JSP容器处理JSP文件需要以下三个阶段:翻译——编译——执行 JSP的页面元素包括 静态内容-HTML静态文本 指令-以“& ...