利用session防止表单重复提交

用户在提交表单的过程中,由于网络等原因,可能重复点击提交按钮,向数据库重复写入或者读取数据,为了防止这种情况发生。

解决方式:

1.客户端防表单重复提交,在前端使用javascript限制。但是在前端并不能完全限制,比如下网页源码更改,重复刷新等。

2.服务端防止表单重复提交,在servlet中限制。

a.由程序产生表单

程序生成一个token值通过session存储

package cn.cast.session;

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{  //产生一个令牌 
	//单例 
	/*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 md = MessageDigest.getInstance("md5");
			byte[] md5 = md.digest(Token.getBytes());
			
			//base64编码  任何数据经过base64编码 都会成为键盘上能够找到的明文字符 
			BASE64Encoder enoder = new BASE64Encoder();
			return enoder.encode(md5);
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			throw new RuntimeException(e);
		}
		
	}
	
}

 jsp网页中通过表单存储一个token值 

<%@ 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="/web2/servlet/DoFormServlet" method="post">
    <input type="hidden" name="token" value="${token }">
             用户名:<input type="text" name="username">
         <input type="submit" value="提交">
    </form>
  </body>
</html>

处理表单。

package cn.cast.session;

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) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("向数据库注册");
	}*/
		
		boolean b = isTokenValid(request);
		
		
		if(!b){
			System.out.println("请不要重复提交");
			return;
			
		}
		request.getSession().removeAttribute("token");
		System.out.println("向数据库注册");
	}
	//判断表单号是否有效;
	private boolean isTokenValid(HttpServletRequest request){
		String client_token = request.getParameter("token");
		if(client_token==null){
			return false;
		}
		String server_token = (String) request.getSession().getAttribute("token");
		if(server_token ==null){
			return false;
			
		}
		if(!client_token.equals(server_token)){
			return false;
		}
		return true;
	}

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

		doGet(request, response);
	}

}
扫描二维码关注公众号,回复: 3946691 查看本文章

猜你喜欢

转载自blog.csdn.net/qq_38125626/article/details/83621850