JavaWeb实现防表单重复提交

1.表单由Servlet生成一个token,用户提交表单时候,会提交token,服务端根据token判断,如果在session中有token和表单提交的相同,则让用户正确提交,并且删除session中的token,

如果用户提交的token错误或者token为null则拒绝提交

a. 生成token类 generateProcessor.java

package com.luowen.formRepeat;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;

import sun.misc.BASE64Encoder;

public class TokenProcessor {

	private static final TokenProcessor gp = new TokenProcessor();
	
	private TokenProcessor(){};
	//单例模式
	public static TokenProcessor getInstance(){
		return gp;
	}
	
	public  String generateToken(){
		String token = System.currentTimeMillis() + " " + new Random().nextInt();
		try {
			//拿到数据指纹
			MessageDigest md = MessageDigest.getInstance("MD5");
			byte[] byt = md.digest(token.getBytes());
			//用Base64编码确保token是可认识的字符
			BASE64Encoder be = new BASE64Encoder();
			return be.encode(byt);
		} catch (NoSuchAlgorithmException e) {
			throw new RuntimeException();
		}
	}
}

 

 b.给表单分配一个token FormSerlve.java

package com.luowen.formRepeat;

import java.io.IOException;

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

/**
 * Servlet implementation class FormRepeat
 */
@WebServlet("/FormServlet")
public class FormServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public FormServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		
		TokenProcessor gp = TokenProcessor.getInstance();
		
		String token = gp.generateToken();
		
		HttpSession session = request.getSession();
		session.setAttribute("token", token);
		request.getRequestDispatcher("/formRepeat.jsp").forward(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

  c.表单jsp页面 formRepeat.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>form repeat submit</title>
</head>
<body>

<h1>Form submit</h1>
<hr/>
<form action="/webDemo/JudgeSubmit" method="post" onsubmit="return doSubmit()">
	Username:<input type="text" name="username" /><br/>
	<input type="submit" value="submit" id="sub" />
	<input type="hidden" name="token" value="${token}" />
</form>
<script>
	function doSubmit(){
		var sub = document.getElementById("sub");
		sub.disabled = 'disabled';		
		return true;
	}
	
</script>
</body>
</html>

 

   d.判断用户提交的JudgeSevlet.java

package com.luowen.formRepeat;

import java.io.IOException;

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

/**
 * Servlet implementation class JudgeSubmit
 */
@WebServlet("/JudgeSubmit")
public class JudgeSubmit extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public JudgeSubmit() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");

		boolean flag = isRepeat(request);
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		if(!flag){
			response.getWriter().print("表单请勿重复提交");
			return;
		}
		
		response.getWriter().print("提交成功弄!");
		return;
		
	}

	private boolean isRepeat(HttpServletRequest request) {

		String clientToken = request.getParameter("token");
		String serverToken = (String) request.getSession().getAttribute("token");
		//判断客服端是否来了token
		if(clientToken == null)return false;
		//判断服务端是否含有token
		if(serverToken == null)return false;
		//判断客户端token和服务端是否相等
		if(!clientToken.equals(serverToken))return false;
		//删除服务端token
		request.getSession().removeAttribute("token");
		return true;
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

   e.jsp通过javascript限制了重复提交,serlvet通过token限制了重复提交.

 

posted @ 2013-12-19 14:57  arvim  阅读(727)  评论(0编辑  收藏  举报