表單重複送出常見的三種情況:
一:送出完表單之後伺服器使用請求轉發來進行頁面跳轉。
這個時候,使用者按下功能鍵F5,就會發起最後一次請求。造成表單重複送出問題。
解決方法:使用重定向來進行跳轉。
二:使用者正常送出伺服器,但是由于網絡延遲等原因,遲遲未收到伺服器的響應,
這個時候,使用者以為送出失敗,然後多次點選送出按鈕,也會造成表單重複送出(可使用Thread.sleep();來模拟)
三:使用者正常送出伺服器,伺服器也沒有延遲,但是送出完成後,使用者退回浏覽器,重新送出。
也會造成表單重複送出。
(二、三解決方法:使用驗證碼)

谷歌驗證碼kaptcha使用步驟如下:
1.導入谷歌驗證碼jar包:kaptcha-2.3.2.jar
2.在web.xml中配置生成驗證碼的Servlet程式
<servlet>
<servlet-name>KaptchaServlet</servlet-name>
<servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>KaptchaServlet</servlet-name>
<url-pattern>/kaptcha.jpg</url-pattern>
</servlet-mapping>
案例代碼:
register.jsp:
<head>
<title>表單注冊——驗證碼</title>
<script type="text/javascript">
$(function () {
//驗證碼重新整理,(給驗證碼的圖檔綁定單擊事件)
$("#code_img").click(function () {
/**
* 在響應事件的function函數中有一個this對象。這個this對象就是目前正在響應事件的dom對象
* src屬性表示驗證碼img标簽的圖檔路徑,它可讀、可寫
* 因為驗證碼切換的時候它每次請求的通路路徑都是相同的,
* 是以浏覽器為了提高效率就會将請求位址放在緩存中,是以當再次發起請求的時候,
* 導緻得到的驗證碼是同一個,是以需要加上一個參數使每次通路的路徑都不相同
* new Date() :擷取時間戳,每次得到的時間都不相同,這個時候就會使每次的請求通路路徑都不相同
* @type {string}
*/
this.src = "${basePath}kaptcha.jpg?d=" + new Date();
});
});
</script>
</head>
<body>
<form action="registerServlet" method="post">
username:<input type="text" name="username" /><br/>
code:<input type="text" name="code" style="width: 60px" />
<img src="kaptcha.jpg" alt="驗證碼生成有誤。" style="width: 130px; height: 50px;" /><br/>
<input type="submit" value="注冊">
</form>
</body>
ok.jsp:
<h1>恭喜你,登入成功。</h1>
RegisterServlet:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1、擷取Session中的驗證碼(KAPTCHA_SESSION_KEY:kaptcha-2.3.2.jar包中Constants中)
String token = (String) request.getSession().getAttribute(KAPTCHA_SESSION_KEY);
// 2、删除Session中的驗證碼(避免重複使用)
request.getSession().removeAttribute(KAPTCHA_SESSION_KEY);
// 3、擷取表單項資訊
String username = request.getParameter("username");
String code = request.getParameter("code");
if (token != null && token.equalsIgnoreCase(code)) {
System.out.println("儲存資料到資料庫:" + username);
response.sendRedirect(request.getContextPath() + "/ok.jsp");
} else {
System.out.println("請不要重複送出表單項。");
}
}
驗證結果: