1.问题来源
很多时候如果用户网络原因,或者延迟原因导致的不停点击表单提交按钮,或者刷新页面,会造成表单重复提交,无效的表单,因此需要实现防止表单重复提交功能
2.原理
首先可以防止用户刷新,处理完成之后用Redirect的方式 跳转到success页面,这样刷新则没有用。但是返回的时候还可以提交一次缓存的数据。
其次每个表单在创建之前都会生成一个令牌,令牌保存在session中,请求表单时生成,当表单提交时判断两个令牌,相同则进入下一步并且删除session中的token,下次如果再次提交相同的表单则会失效,因为session中没有此令牌。
3.html
<body>
<%
long token=System.currentTimeMillis(); //产生token
session.setAttribute("token",token);
%>
<form action="isRepeat" method="post">
<input type="text" name="username"/>
<input type="text" name="password"/>
<input type="hidden" value="<%=token %>" name="Reqtoken"/> <!-- 作为hidden提交 -->
<input type="submit" value="提交"/>
</form>
</body>
4.servlet
String token = req.getParameter("Reqtoken");// 获取表单上面的时间戳T1
HttpSession session=req.getSession();
String tokenInSession = ""+session.getAttribute("token");
System.out.println("Session in Token: " + tokenInSession);
System.out.println("表单的Token:" + token+"\n------------");
if (tokenInSession!=null && token!=null && token.equals(tokenInSession)) {
resp.getWriter().println("ok ");
session.removeAttribute("token");
} else { //如果禁止缓存,返回会 重新请求,tokenInSession 是不会为空的
System.out.println("重复提交,或者有错误");//或者有错误,直接访问servlet等
resp.sendRedirect("index.jsp");
return;
}
resp.sendRedirect("success.jsp"); //此句子导致刷新无效