session的使用:防止表单重复提交

服务器端防止表单重复提交思路:

  1. 由服务器端发给每个表单唯一的随机数,作为表单令牌
  2. 每个客户端在服务器端保存的session对象中,存储生成的表单令牌
  3. 客户端提交表单后进行表单令牌的验证,如果客户端与服务器中的令牌一致,那么可以提交,并且提交后移除session中的令牌
  4. 如果不一致,说明已经注册过了,从而终止提交动作
  5. 令牌发生器采用单例模式,获取数据摘要,并进行base64编码,得到统一长度的随机令牌字符串

登录servlet:

package com.franky.login;

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

import sun.misc.BASE64Encoder;

/**
 * @作者 franky
 * @描述   防止表单重复提交
 * @日期 2015-1-12 下午04:35:47
 */
public class LoginForm extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//生成随机数,将随机数写入表单
		TokenProcessor token = TokenProcessor.getInstance();
		String encode = token.generateToken();
		System.out.println(encode);
		//随机数写入session
		HttpSession session = request.getSession();
		session.setAttribute("token", encode);
		//随机数写入表单
		request.getRequestDispatcher("/login2.jsp").forward(request, response);
	}

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

}
/**
 * 
 * @作者 franky
 * @描述  随机数生成器,采用单例模式,防止重复随机数路领跑
 * @日期 2015-1-12 下午04:35:33
 */
class TokenProcessor{
	private static final TokenProcessor instance = new TokenProcessor();
	private TokenProcessor(){
		
	}
	public static TokenProcessor getInstance(){
		return instance;
	}
	
	/**生成随机令牌的方法
	 * @return 返回随机字符串随机令牌
	 */
	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();
			String encode = encoder.encode(md5);
			return  encode;
			
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		
		return null;
	}
}
转发的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>


<script type="text/javascript">
	var isSubmit = false;
	function doSubmit(){
		if(!isSubmit){
			isSubmit = true;
			return true;
		}else{
			window.alert("请不要重复注册");
			return false;
		}
	}
</script>
	
</head>
<body>
	<form  action="/javawebdemos/servlet/CheckServlet" method="post" >
		<input type="hidden" name="token" value="${token}"/>
		username:<input type="text" name="username"><br/>
		<input type="submit" value="submit" onclick="return doSubmit()" >
	</form>
</body>
</html>

验证servlet:

package com.franky.login;

import java.io.IOException;

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

/**
 * @作者 franky
 * @描述   防止表单重复提交,利用session中的表单令牌
 * @日期 2015-1-12 下午04:43:02
 */
public class CheckServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//验证表单是否有效
		boolean isValid = isTokenValid(request);
		
		if(!isValid){
			System.out.println("请不要重复注册!");
			return;
		}
			request.getSession().removeAttribute("token");
			System.out.println("注册成功");
		
	}

	/**
	 * 检验表单令牌是否有效
	 * @param request 传入request对象
	 * @return 返回令牌是否有效
	 */
	private boolean isTokenValid(HttpServletRequest request) {
		
		String c_token = request.getParameter("token");
		//验证表单令牌是否为空,为空返回false
		if(c_token==null){
			return false;
		}
		
		HttpSession session = request.getSession();
		String s_token = (String) session.getAttribute("token");
		//验证服务器端令牌是否为空,为空返回false
		if(s_token==null){
			return false;
		}
		//验证两端的令牌是否相同,不相同返回false
		if(!s_token.equals(c_token)){
			return false;
		}
		//排除以上三种情况后,返回true
		return true;
	}

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

}



猜你喜欢

转载自blog.csdn.net/franky814/article/details/42644819
今日推荐