在平时开发中,如果网速比较慢的情况下,或者远程有延迟,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,这样会出现表单的重复提交,造成向服务器发送两次请求,所以我们在开发中必须防止表单
重复提交。
表单重复提交的情况:
1.第一次单击提交之后,在没有提交成功情况下,又单击提交按钮。
2.提交完表单之后,刷新网页。
3.用户提交表单后,点击浏览器的【后退】按钮回退到表单页面后进行再次提交。
解决方案:
网上很多解决办法,一下连接解决方案比较全面,还有图文演示:https://www.cnblogs.com/xdp-gacl/p/3859416.html
自己解决办法:利用session,在表单中做一个标记,提交到servlet时候,检查标记是否在且和预定义标志一直,若一直,则受理请求,并销毁标记,若不一致,或者没有标记,则直接响应消息,“表单重复提交”。
步骤:
》在原表单页面,随机生成一个token
》在原表单页面,将token值放入到session属性当中
》token属性值也放在隐藏域当中
》在目标页面中,:获取session和隐藏域token值,比较两个值是否一致,若一致,受理请求,且把session与中的session属性清除。
表单页面 :
<%@page import="org.apache.catalina.Session"%>
<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
String token=new Date().getTime()+"";
HttpSession sessio= request.getSession(true);
sessio.setAttribute("token", token);
%>
<h1>Step-1:选择要购买的书籍</h1>
<form action="<%=request.getContextPath() %>/procesStep1" method="post">
<input type="hidden" name="token" value="<%=token%>">
<table cellpadding="10" cellspacing="0" border="1px">
<tr>
<td>书名</td>
<td>购买</td>
</tr>
<tr>
<td>Java</td>
<td><input type="checkbox" name="book" value="java"></td>
</tr>
<tr>
<td>C++</td>
<td><input type="checkbox" name="book" value="c++"></td>
</tr>
<tr>
<td>Python</td>
<td><input type="checkbox" name="book" value="python"></td>
</tr>
<tr>
<td>web</td>
<td><input type="checkbox" name="book" value="web"></td>
</tr>
<tr>
<td colspan="2"> <input type="submit" value="submit"></td>
</tr>
</table>
</form>
</body>
</html>
目标服务器:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//1550936037932
String sessionToken = (String)request.getSession().getAttribute("token");
String requestToken = request.getParameter("token");
if(sessionToken!=null&&sessionToken.equals(requestToken)) {
request.getSession().removeAttribute("token");
}else {
//request.getRequestDispatcher("/shoppingCart/relogin.jsp");
response.sendRedirect(request.getContextPath()+"/shoppingCart/relogin.jsp");
return ;
}
//request.setCharacterEncoding("UTF-8");
ServletContext servletContext = request.getServletContext();
String servletContextName = servletContext.getServletContextName();
ServletConfig servletConfig = getServletConfig();
String[] parameterValues = request.getParameterValues("book");
request.getSession().setAttribute("book", parameterValues);
String contextPath = request.getContextPath();
System.out.println(contextPath);
//下面是绝对路径
// response.sendRedirect(contextPath+"/shoppingCart/step_2.jsp");
//相对路径
response.sendRedirect("shoppingCart/step_2.jsp");
}