在平時開發中,如果網速比較慢的情況下,或者遠端有延遲,使用者送出表單後,發現伺服器半天都沒有響應,那麼使用者可能會以為是自己沒有送出表單,就會再點選送出按鈕重複送出表單,這樣會出現表單的重複送出,造成向伺服器發送兩次請求,是以我們在開發中必須防止表單
重複送出。
表單重複送出的情況:
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" >
<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");
}