为了防止用户在客户端重复提交表单,要分析从客户端和服务端对重复提交的表单就行处理,首先是客户端处理重复提交表单,使用JavaScript方法,第一种是只允许表单提交一次,后来的不能再提交,第二种是提交一次后按钮变成不可用,下面是代码的实现
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title><script type="text/javascript">/* var isCommit = false; function doSubmit(){ if(! isCommit){ isCommit = true; return true; } else{ return false; } }*/ function doSubmit(){//使提交按钮再提交完成后不可用 var input = document.getElementById("submit"); input.disabled='disabled'; return true; }</script></head><body><form action="/Web/servlet/DoFormServlet" method="post" onsubmit="return doSubmit()">用户名:<input type="text" name="username"><br><input id="submit" type="submit" value="提交" ></form></body></html>
但是仅仅在客户端进行处理是远远不够的,这叫只能防的了君子防不了小人,因为可以根据服务器的提交地址自己写一个表单或者去掉JavaScript代码进行自己的提交,这样仍旧无法阻止客户端的表单的重复提交,下面就需要在服务端做手脚,首先需要写一个Servlet用来产生表单,他的想法是产生一个唯一的Id ,通过随机数才产生,然后付到表单上,当表单提交的时候,根据验证这个ID号来判断时候是重复提交表单。
当然,这个随即数的产生不简单,首先使用单例设计模式,减少随机数产生的相似性概率,然后使用当前时间毫秒数加上一个随机数来进行,然后因为这样产生的随机数大小长度不等,所以进行md5编码后再进行BASE64编码,产生长度相等的而且字符都是键盘上可以识别的随机数,放到表单的隐藏域里面去。这个BASE64编码在网络传输中也有很好的作用,表单提交后,处理的Servlet根据放入到Session中的随机数来验证是不是重复提交,如果不是,就进行下面的比如放入到数据库等操作,如果是,则回复请求,说明表单重复提交。下面上代码
首先是产生表单的Servlet
package com.bird.form;import java.io.IOException;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 { /** * 写给浏览器一个表单,并且防止多次重复提交而创建随机数 * @author Bird */ private static final long serialVersionUID = 1L; 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{//令牌发生器 /** * 1.把构造方法私有 * 2.自己创建一个 * 3.对外暴露一个方法,允许获得创建的对象 */ 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 md5 = MessageDigest.getInstance("md5"); byte[] md = md5.digest(token.getBytes()); //base64进行编码 BASE64Encoder encoder = new BASE64Encoder(); return encoder.encode(md); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } }}
然后是那个JSP页面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title></head><body> <form action="/Web/servlet/DoFormServlet" method="post"> <input type="hidden" name="token" value="${token}"> 用户名:<input type="text" name="username"><br/> <input type="submit" value="提交"> </form></body></html>
然后是处理提交请求的Servlt
package com.bird.form;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class DoFormServlet extends HttpServlet { /** * 处理表单的重复提交 * @author Bird */ private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { boolean b = isTokenValue(request); if(!b){ System.out.println("请不要重复提交"); return; } request.getSession(false).removeAttribute("token"); System.out.println("向数据库中注入数据"); } private boolean isTokenValue(HttpServletRequest request) { String clinet_token = request.getParameter("token"); if(clinet_token == null){ return false; } String server_token = (String) request.getSession(false).getAttribute("token"); if(server_token == null){ return false; } if(!server_token.equals(clinet_token)){ return false; } return true; } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }}
再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow