客户端服务端防止用户重复提交表单

一、什么是表单重复提交?
当网络有延迟时,用户提交的表单等数据还没有完成此次提交,但用户又多次点击提交,造成用户数据在数据库或存储中被提交多次。
利用线程延迟,简单模拟重复提交。
表单页面为form.html
[html] view plain copy



form.html

<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
<meta http-equiv="description" content="this is my page">  
<meta http-equiv="content-type" content="text/html; charset=UTF-8">  <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->  



用户名 :



处理提交请求的servlet为DoFormServlet.java
[java] view plain copy
package SessionDemo;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class DoFormServlet extends HttpServlet
{

public void doGet(HttpServletRequest request, HttpServletResponse response)  throws ServletException, IOException  
{  String username = request.getParameter("username");  //利用线程休眠,模拟网络延迟  try  {  Thread.sleep(1000*3);  } catch (InterruptedException e)  {  e.printStackTrace();  }  System.out.println("向数据库中注册数据。");  
}  public void doPost(HttpServletRequest request, HttpServletResponse response)  throws ServletException, IOException  
{  doGet(request, response);  
}  

}
在浏览器中加载form.html

当用户反复点击“提交”时,就造成了重复提交。

二、解决方法一:利用javascript阻止
其他不变,将form.html修改为
[html] view plain copy



form.html

<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
<meta http-equiv="description" content="this is my page">  
<meta http-equiv="content-type" content="text/html; charset=UTF-8">  <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->  


var isCommitted = false;
function dosubmit()
{
if(!isCommitted)
{
isCommitted=true;
return true;
}
else
{
return false;
}
}




用户名 :




这样在浏览器中加载form.html后,点击“提交”,终端中只会输出一次”向数据库中注册数据。”,表明成功阻止表单反复提交。
以上form.html可以进一步优化,当用户点击“提交”后,“提交”按钮应该变为灰色不可用。
[html] view plain copy



form.html

<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
<meta http-equiv="description" content="this is my page">  
<meta http-equiv="content-type" content="text/html; charset=UTF-8">  <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->  


function dosubmit()
{
var input = document.getElementById("submit");
input.disabled = 'disabled';
return true;
}




用户名 :




利用javascript的方法不能完全防止用户恶意重复提交,例如:用户可以将form.html保存后修改,还可以在点击“提交”后重复刷新页面,从而实现反复提交。
三、解决方法二:利用服务器端Session防止表单重复提交。
其中FormServlet.java为
[java] view plain copy
package SessionDemo;

import java.io.IOException;
import java.io.PrintWriter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import sun.misc.BASE64Encoder;

public class FormServlet extends HttpServlet
{

public void doGet(HttpServletRequest request, HttpServletResponse response)  throws ServletException, IOException  
{  //产生随机数表单号  TokenProcessor tp = TokenProcessor.getInstance();  String token = tp.generateToken();  request.getSession().setAttribute("token",token);  request.getRequestDispatcher("/form.jsp").forward(request, response);  
}  public void doPost(HttpServletRequest request, HttpServletResponse response)  throws ServletException, IOException  
{  doGet(request, response);  
}  

}

//设计为单例模式
class TokenProcessor
{
private TokenProcessor(){};
private static final TokenProcessor instance = new TokenProcessor();

public static TokenProcessor getInstance()  
{  return instance;  
}  public String generateToken()  
{  //获得随机数字符串  String token = System.currentTimeMillis() + new Random().nextInt() + "";  //获得数据摘要  try  {  MessageDigest md = MessageDigest.getInstance("md5");  byte[] md5 = md.digest(token.getBytes());  //利用base64编码防止乱码。  BASE64Encoder encoder = new BASE64Encoder();  return encoder.encode(md5);  } catch (NoSuchAlgorithmException e)  {  throw new RuntimeException(e);  }  
}  

}
添加form.jsp
[plain] view plain copy
<%@ page language=”java” import=”java.util.*” pageEncoding=”UTF-8”%>







用户名




将DoFormServlet.java修改为
[java] view plain copy
package SessionDemo;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class DoFormServlet extends HttpServlet
{

public void doGet(HttpServletRequest request, HttpServletResponse response)  throws ServletException, IOException  
{  String username = request.getParameter("username");  boolean b = isTokenValue(request);  if (!b)  {  System.out.println("请不要重复提交。");  return;  }  request.getSession().removeAttribute("token");  System.out.println("向数据库中注册数据。");  
}  //判断表单号是否有效  
private boolean isTokenValue(HttpServletRequest request)  
{  String clientToken = request.getParameter("token");  if(clientToken==null)  {  return false;  }  String serverToken = (String) request.getSession().getAttribute("token");  if(serverToken==null)  {  return false;  }  if (!clientToken.equals(serverToken))  {  return false;  }  return true;  
}  public void doPost(HttpServletRequest request, HttpServletResponse response)  throws ServletException, IOException  
{  doGet(request, response);  
}  

}
再浏览器中加载FormServlet

点击“提交”后跳转

终端显示用户提交

这时即使用户点击“刷新”,也不能实现重复提交。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/331021.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

405: HTTP method GET is not supported by this URL

【0】README1&#xff09;本文旨在解决 405: HTTP method GET is not supported by this URL 的问题&#xff1b;2&#xff09;本文raw idea is checkouted from http://stackoverflow.com/questions/5370633/405-http-method-get-is-not-supported-by-this-url【1】解决方法…

史上最全Redis面试题

转载自 史上最全Redis面试题及答案。1、什么是Redis&#xff1f; 2、Redis相比memcached有哪些优势&#xff1f; 3、Redis支持哪几种数据类型&#xff1f; 4、Redis主要消耗什么物理资源&#xff1f; 5、Redis的全称是什么&#xff1f; 6、Redis有哪几种数据淘汰策略&#xff1…

多线程的三种实现方法

http://blog.csdn.net/aboy123/article/details/38307539

stomp 连接错误: Whoops! Lost connection to http://localhost:8080/spring13/stomp 的解决方法

【0】README 1&#xff09;本文旨在给出 stomp 连接错误&#xff1a; Whoops! Lost connection to http://localhost:8080/spring13/stomp 的解决方法&#xff1b;you can also refer to this link http://stackoverflow.com/questions/29247956/whoops-lost-connection-to-u…

Spring面试题(70道,史上最全)

转载自 Spring面试题&#xff08;70道&#xff0c;史上最全&#xff09;1.什么是spring?2.使用Spring框架的好处是什么&#xff1f;3.Spring由哪些模块组成?4.核心容器&#xff08;应用上下文)模块。5.BeanFactory–BeanFactory实现举例。6.XMLBeanFactory7.解释AOP模块8.解释…

纯干货,Spring-data-jpa详解,全方位介绍。

http://www.cnblogs.com/dreamroute/p/5173896.html

springmvc(18)使用WebSocket 和 STOMP 实现消息功能

【0】README1&#xff09;本文旨在 介绍如何 利用 WebSocket 和 STOMP 实现消息功能&#xff1b;2&#xff09;要知道&#xff0c; WebSocket 是发送和接收消息的 底层API&#xff0c;而SockJS 是在 WebSocket 之上的 API&#xff1b;最后 STOMP&#xff08;面向消息的简单文本…

分享一套高级Java笔试题(实拍高清图)

转载自 分享一套高级Java笔试题(实拍高清图)下面是部分分享原图

使用工具将SQLServer转MYSQL的方法(连数据)

http://www.cnblogs.com/kissdodog/p/3929072.html

openfire client聊天消息交互和存储离线(在线)消息记录策略

【0】如何将离线消息存档&#xff0c;且在接收者上线之后&#xff0c;推送消息到接收者发送方发送消息 -> 检测接收方是否在线 -> -> y -> 发送在线消息 -> 发送成功后&#xff0c;存档到消息记录&#xff1b; -> n -> 修改数据包&#xff08;XML流&#…

Spring boot 入门篇

http://www.cnblogs.com/ityouknow/p/5662753.html

通往大神之路,百度Java面试题前200页。

转载自 通往大神之路&#xff0c;百度Java面试题前200页。基本概念 操作系统中 heap 和 stack 的区别什么是基于注解的切面实现什么是 对象/关系 映射集成模块什么是 Java 的反射机制什么是 ACIDBS与CS的联系与区别Cookie 和 Session的区别fail-fast 与 fail-safe 机制有什么区…

springmvc(17)异步消息简介(部分)

【0】README1&#xff09;本文旨在 intro 异步消息的 相关基础知识&#xff1b;【1】intro【1.1】发送消息1&#xff09;intro&#xff1a;间接性是异步消息的关键所在&#xff1b;2&#xff09;当一个应用向另一个应用发送消息时&#xff0c;两个应用之间没有直接的联系。相反…

搭建一个简单的Spring boot+maven项目

http://www.cnblogs.com/suncj/p/4065589.html

去BAT面试完的Mysql面试题总结(55道)

转载自 去BAT面试完的Mysql面试题总结&#xff08;55道&#xff0c;带完整答案&#xff09;55道互联网大公司的经典面试题&#xff0c;全部答对月薪5W没问题。1、一张表里面有ID自增主键&#xff0c;当insert了17条记录之后&#xff0c;删除了第15,16,17条记录&#xff0c;再把…

js解析json数组+java对象转json字符串

function checkoutUserlist(){ // js 解析json数组var statuslist [{"isAvailabe":"1","name":"pacoson"},{"isAvailabe":"0","name":"tangtang"},{"isAvailabe":"0",&…

【双11劲爆干货】阿里高级Java面试题(首发,70道)

转载自 【双11劲爆干货】阿里高级Java面试题&#xff08;首发&#xff0c;70道&#xff0c;带详细答案&#xff09; 整理的70道阿里的Java面试题&#xff0c;都来挑战一下&#xff0c;看看自己有多厉害。下面题目都带超详细的解答&#xff0c;详情见底部。 1、java事件机制包括…

系统项目源码

http://blog.sina.com.cn/s/blog_4b5bc011010114zu.html

http长/短轮询和WebSocket 的介绍和比较

【1】http协议介绍1&#xff09;介绍&#xff1a;http协议是请求/响应范式的&#xff0c;每个http 响应都对应一个 http 请求&#xff0c;http协议是无状态的&#xff0c;多个http请求之间是没有关系的&#xff1b;2&#xff09;http协议的被动性&#xff1a;在标准的HTTP请求响…