我们都知道可以通过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防止表单进行重复提交的更多相关文章

  1. Session机制三(表单的重复提交)

    1.表单的重复提交的情况 在表单提交到一个servlet,而servlet又通过请求转发的方式响应了一个JSP页面,这个时候地址栏还保留这servlet的那个路径,在响应页面点击刷新. 在响应页面没有 ...

  2. php-- 避免表单的重复提交

    用户提交表单时可能因为网速的原因,或者网页被恶意刷新,致使同一条记录重复插入到数据库中,这是一个比较棘手的问题.我们可以从客户端和服务器端一起着手,设法避免同一表单的重复提交. 1.使用客户端脚本 提 ...

  3. Spring MVC表单防重复提交

    利用Spring MVC的过滤器及token传递验证来实现表单防重复提交. 创建注解 @Target(ElementType.METHOD) @Retention(RetentionPolicy.RU ...

  4. HttpSession解决表单的重复提交

    1). 重复提交的情况: ①. 在表单提交到一个 Servlet, 而 Servlet 又通过请求转发的方式响应一个 JSP(HTML) 页面, 此时地址栏还保留着 Serlvet 的那个路径, 在响 ...

  5. Struts2 - 表单的重复提交问题

    用户重复提交表单在某些场合将会造成非常严重的后果.例如,在使用信用卡进行在线支付的时候,如果服务器的响应速度太慢,用户有可能会多次点击提交按钮,而这可能导致那张信用卡上的金额被消费了多次.因此,重复提 ...

  6. 使用aop注解实现表单防重复提交功能

    原文:https://www.cnblogs.com/manliu/articles/5983888.html 1.这里采用的方法是:使用get请求进入表单页面时,后台会生成一个tokrn_flag分 ...

  7. HttpSession之表单的重复提交 & 验证码

    如果采用 HttpServletResponse.sendRedirct() 方法将客户端重定向到成功页面,将不会出现重复提交问题 1.表单的重复提交 1). 重复提交的情况: ①. 在表单提交到一个 ...

  8. struts2 文件的上传下载 表单的重复提交 自定义拦截器

    文件上传中表单的准备 要想使用 HTML 表单上传一个或多个文件 须把 HTML 表单的 enctype 属性设置为 multipart/form-data 须把 HTML 表单的method 属性设 ...

  9. php中如何防止表单的重复提交

    在php中如何防止表单的重复提交?其实也有几种解决方法. 下面小编就为大家介绍一下吧.需要的朋友可以过来参考下 代码: <?php /* * php中如何防止表单的重复提交 * by www.j ...

随机推荐

  1. qualcomm batch 烧录脚本

    在烧录android系统候用到了windows的批处理文件,拿出来分析一下,顺便记录一下高通平台烧录系统的命令. @echo off :: @ :不显示后面的命令,就是后面的"echo of ...

  2. MongoDB mongod.exe或mongo.exe双击一闪就关闭

    场景: 在 D:\data\ 创建 db目录之后,运行 mongod -repair 原因: 磁盘满了,没有空间了. 解决方法: 把 MongoDB\data 下的 lock 文件删掉,清理下磁盘空间 ...

  3. Java如何使用线程解决生产者消费者问题?

    在Java编程中,如何使用线程解决生产者消费者问题? 以下示例演示如何使用线程解决生产者消费者问题. package com.yiibai; public class ProducerConsumer ...

  4. Maven快照

    大型应用软件一般由多个模块组成,一般它是多个团队开发同一个应用程序的不同模块,这是比较常见的场景.例如,一个团队正在对应用程序的应用程序,用户界面项目(app-ui.jar:1.0) 的前端进行开发, ...

  5. e782. 排列JList中的项

    By default, the items in a list are arranged vertically, in a single column, as in: item1 item2 ... ...

  6. (原)linux下利用cmake来编译jthread开源库

    其实上次在用hisi3531平台的时候,就已经编译过一次这个库了,这次换了平台环境,交叉编译器变成了arm-hisiv100-linux-工具链,所以,没办法只能重新来过. 因为之前编译过,所以这次还 ...

  7. nodejs基础 -- web模块

    什么是 Web 服务器? Web服务器一般指网站服务器,是指驻留于因特网上某种类型计算机的程序,Web服务器的基本功能就是提供Web信息浏览服务.它只需支持HTTP协议.HTML文档格式及URL,与客 ...

  8. php -- 取整数

    PHP取整数函数常用的四种方法,下面收集了四个函数: 经常用到取整的函数,今天小小的总结一下!其实很简单,就是几个函数而已--主要是:ceil,floor,round,intval ceil — 进一 ...

  9. ibatis中 $ 于 # 的 区别?

    转自: http://www.blogjava.net/lsbwahaha/archive/2009/04/16/266026.html 一个项目中在写ibatis中的sql语句时,where use ...

  10. 如何在linux中批量建立用户并设置随机密码

    Ubuntu是基于linux的免费开源操作系统,同时也是真正意义上的“多任务多用户”操作系统,既然是多用户系统,自然就涉及到创建多个用户的问题.同时由于Ubuntu系统中的root用户具有最高权限,无 ...