利用session防止重复提交
思路:
前端控制:在点击提交按钮后设置按钮不可用。
后台控制:利用session,在初次进入表单页面的时候前生成一个随机token,将token保存到session并返回到前端页面,前端提交页面,后台获取前端提交的token值与session中的token比较。
主要代码:
package servlet; import java.io.IOException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import servlet.token.TokenProccessor; public class FormServlet extends HttpServlet{ private static final long serialVersionUID = 1L; @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 生成token
String token = TokenProccessor.getInstance().makenToken();
System.out.println("FormServlet中生成的token:" + token); req.getSession().setAttribute("token", token);
// 进入表单提交页面
req.getRequestDispatcher("/form.jsp").forward(req, resp);
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doGet(req, resp);
}
}
处理提交的Servlet
package servlet; import java.io.IOException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class DoFormServlet extends HttpServlet{ private static final long serialVersionUID = 1L; @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
// 判断是否重复提交
boolean b = isRepeatSubmit(req); if (true == b) {
System.out.println("重复提交");
return ;
} req.getSession().removeAttribute("token");
System.out.println("处理请求!");
String userName = req.getParameter("username");
try {
// 模拟系统处理
Thread.sleep(3*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("插入数据:"+userName);
} private boolean isRepeatSubmit(HttpServletRequest req) { String client_token = req.getParameter("token");
// 用户提交表单时不存在token 表示直接刷新页面重复提交
if (client_token == null) {
return true;
}
// 返回后再次提交,当前用户不存在token重复提交
String server_token = (String) req.getSession().getAttribute("token");
if(server_token==null){
return true;
}
// Session中令牌与表单提交不一致 重复提交
if (!client_token.equals(server_token)) {
return true;
}
return false;
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doGet(req, resp);
} }
页面
<%@ 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="${pageContext.request.contextPath }/DoFormServlet" method="post">
<%-- <input type="hidden" name="token" value="<%=session.getAttribute("token")%>"> --%>
用户名:<input type="text" name="username">
<input type="hidden" name="token" value="${token }">
<input type="submit" value="提交" id="submit">
</form>
</body> <script type="text/javascript">
function doSubmit(){
var btnSubmit = document.getElementById("submit");
btnSubmit.disabled="disabled";
return true;
}
</script>
</html>