思想
- 打开页面时,生成一个token,将这个token保存到Session中,
- 在表单中提供一个隐藏域,设置其值为每1步中生成的token
- 在处理表单的Servlet中,获取表单隐藏域中的token与Session中的token进行比较,比较完之后直接将Session中的token删除
- 如果相等可以提交,
- 如果不相等,提示用户不能重复提交
示例
打开页面的Servlet
java
@WebServlet("/open")
public class OpenServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//生成唯一的令牌
String token = UUID.randomUUID().toString();
//将生成的令牌放到Session中
request.getSession().setAttribute("token", token);
//
response.sendRedirect("demo.jsp");
}
}
页面 demo.jsp
html
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head>
<title>防止表单的重复提交</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
</head>
<body>
<form action="${pageContext.request.contextPath}/demo/deal" method="post">
<input type="hidden" name="token" value="${sessionScope.token}"/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
处理表单请求的Servlet
java
@WebServlet("/deal")
public class DealServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String fToken = request.getParameter("token");//隐藏域中的令牌
HttpSession session = request.getSession();
String sToken = (String) session.getAttribute("token");
//检查令牌
if(fToken.equals(sToken)){
//把令牌从HttpSession中删除掉
session.removeAttribute("token");
}else{
response.getWriter().write("请不要重复提交请求");
}
}
}