首页 > 代码库 > session------>防表单重复提交

session------>防表单重复提交

方法一:用js控制表单提交---》但是容易在客户端被篡改代码,还是要加的

方法二:session

先给每一个表带上唯一的标志,再把标志存入session

当session中标志和表上标志都不为空 ,且相等的情况下,提交表单成功,否则失败

 

下面是demo

目的:访问FormServlet----->加上标记后,转发到form.jsp----->提交的DoFormServlet.java来判断标记是否相等

FormServlet.java

/**
 * 产生表单
 */
@WebServlet("/FormServlet")
public class FormServlet extends HttpServlet {    
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
        //生产随机号
        TokenProcessor tp=new TokenProcessor();
        String token=tp.generateToken();
        
        //在session中存入标记
        request.getSession().setAttribute("token", token);
        
        //转发到form.jsp
        request.getRequestDispatcher("/form.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);
    }

}
class TokenProcessor{//令牌
    /**
     * 1.构造方法私有
     * 2.自己构造一个
     * 3.对外暴露一个方法,允许获取上面创建的对象
     * 
     */
    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");//通过md5算法,得到数据指纹,数据指纹大小是一样的
            byte[] md5=md.digest(token.getBytes());
            //base64--->通过这个算法把字节转化成范围(0--63)键盘可见的字符(二进制的三个字节转化成四个字节)
            BASE64Encoder encoder=new BASE64Encoder();
            return encoder.encode(md5);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }   
}

 

 form.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="/day06/DoFormServlet" method="post ">
<input type="hidden" name="token" value="http://www.mamicode.com/${token}">
用户名:<input type="text" name="username"  />
<input type="submit" value="http://www.mamicode.com/提交">
</body>
</html>

 DoFormServlet.java

/**
 * 判断标记
 */
@WebServlet("/DoFormServlet")
public class DoFormServlet extends HttpServlet {
	protected 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=isTokenvalid(request);//判断是否重复提交
		if(!b){
			out.write("请不要重复提交表单");
			return;
		}
		request.getSession(false).removeAttribute("token");//提交成功,session标记失效
		out.write("处理表单");
		
	}

	/**
	 * @param request
	 * @return
	 */
	private boolean isTokenvalid(HttpServletRequest request) {
		String client_token=request.getParameter("token");//表单上的标记不为空
		if(client_token==null){
			return false;
		}
		String token=(String) request.getSession(false).getAttribute("token");
		if(token==null){//存入session中标记不为空
			return false;
		}
		if(!token.equals(client_token)){//session中的标记和表单一致,表单未被篡改
			return false;
		}	
		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);
	}
}

 

session------>防表单重复提交