防止表单重复提交

在注册用户或者其他的时候   必须要防止恶意的表单重复提交, 其中可是使用javascript代码在点击提交按钮之后将按钮变灰 防止 重复提交  但是  这只可以防止平常的用户表单提交,对于懂技术的恶意用户,使用JavaScript无法防止恶意提交  ,这时候 便需要在服务器中防止  。

防止的具体方法思路是:

创建一个令牌,当用户运行提交表单的servlet时,利用令牌随机创建一个字符串, 并将其放在隐藏表单中(hidden属性)  然后将这个令牌也放在session中 用户提交表单跳转到下一个页面,在这个页面中  判断令牌是否 有效,就是判断session中的令牌和 表单中的令牌是否一致,若不一致则无效。  在提交成功后应该将session中的令牌删除,在下次重复提交时就可以判断不一致,阻止提交!!!

其中包括2个servlet和一个jsp

第一个servlet是 用来创建session和 产生随机数的  将随机数放入表单中  这样可以防止恶意用户自己写一个表单提交  因为我们的表单有令牌  他的没有 然后第一个servlet跳转到jsp页面   


在jsp页面课直接获取token令牌值  使用  ${token}即可   其中令牌值  用hidden 属性隐藏   

点击提交后  在第二个servlet处理结果   

所以 第二个servlet来判断是否重复提交  方法就是对比session中和表单中的令牌是否一致   如果一致  成功  并且删除session  即可



具体代码如下:

servlet1:

package cn.sessions;

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 {

		
		String token = TokenProcess.getInstance().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 TokenProcess{
	//将构造函数设为私有   即外界不可创建对象,可保证对象的唯一性  
	private TokenProcess(){}
	
	private static final TokenProcess instance = new TokenProcess();
	//像外界提供一个获取该唯一对象的接口
	public static TokenProcess getInstance(){
		return instance;
	}
	public String generateToken(){
		//通过当前时间毫秒值和随机函数 获取一个随机数
		String token = System.currentTimeMillis()+new Random().nextInt()+"";
		
		//由于上述获取的随机数长度不定  所以要采用数据摘要类获取固定长度的随机数  MessageDigest
		try {
			MessageDigest md = MessageDigest.getInstance("md5");
			byte[] md5 = md.digest(token.getBytes());
			
			//又由于md5数组如果转换为字符串基本上会是乱码  所以要用Base64Encoder 来进行转换  成字符串
			BASE64Encoder encoder = new BASE64Encoder();
			return encoder.encode(md5);
			
			
		} catch (NoSuchAlgorithmException e) {
			throw new RuntimeException();
		}
		
		
	}
}

form.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'form.jsp' starting page</title>
    
	

  </head>
  
  <body>
	<form action="/cooks/servlet/DoFormServlet">
			<input type="hidden" name="token" value="${token}">
  			用户名: <input type="text" name="username"> <br/>
  			<input type="submit" value="提交">
  	</form>
  
  </body>
</html>

第二个servlet(判断是否重复提交) :


package cn.sessions;

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;
import javax.servlet.http.HttpSession;

public class DoFormServlet extends HttpServlet {

	
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter out = response.getWriter();
		
		boolean b = isTokenRiget(request);
	
		if(!b){
			System.out.println("请不要重复提交");
		    return;
		}
		request.getSession().removeAttribute("token");
		System.out.println("写入数据库");
		
	}


	/**
	 * 此函数的作用是用来判断token是否有效的 
	 * */
	private boolean isTokenRiget(HttpServletRequest request) {
		String token = request.getParameter("token");
		HttpSession session = request.getSession();
		String tokenSession = (String) session.getAttribute("token"); 
		if(token==null){
			return false;
		}
		if(tokenSession==null)
			return false;
		if(!tokenSession.equals(token)){
			return false;
		}
		return true;
		
	}


	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		doGet(request, response);
	}

}





你可能感兴趣的:(防止表单重复提交)