第一種(JavaScript):
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<html>
? <head>
? ? <title>Form表單</title>
? ? ? ? <script type="text/javascript">
? ? ? ? var isCommitted = false;//表單是否已經(jīng)提交標識廉白,默認為false
? ? ? ? function dosubmit(){
? ? ? ? ? ? if(isCommitted==false){
? ? ? ? ? ? ? ? isCommitted = true;//提交表單后纺非,將表單是否已經(jīng)提交標識設置為true
? ? ? ? ? ? ? ? return true;//返回true讓表單正常提交
? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? return false;//返回false那么表單將不提交
? ? ? ? ? ? }
? ? ? ? }
? ? </script>
? </head>
? <body>
? ? ? <form action="${pageContext.request.contextPath}/servlet/DoFormServlet" onsubmit="return dosubmit()" method="post">
? ? ? ? 用戶名:<input type="text" name="username">
? ? ? ? <input type="submit" value="提交" id="submit">
? ? </form>
? </body>
</html>
第二種(利用Session防止表單重復提交)
在服務器端生成一個唯一的隨機標識號token,同時在當前用戶的Session域中保存這個Token烘贴。然后將Token發(fā)送到客戶端的Form表單中,在Form表單中使用隱藏域來存儲這個Token涕侈,表單提交的時候連同這個Token一起提交到服務器端神妹,然后在服務器端判斷客戶端提交上來的Token與服務器端生成的Token是否一致拳昌,如果不一致趴乡,那就是重復提交了,此時服務器端就可以不處理重復提交的表單焙糟。如果相同則處理表單提交口渔,處理完后清除當前用戶的Session域中存儲的標識號。
在下列情況下穿撮,服務器程序將拒絕處理用戶提交的表單請求:
存儲Session域中的Token與表單提交的Token不同缺脉。
當前用戶的Session中不存在Token。
用戶提交的表單數(shù)據(jù)中沒有Token悦穿。
1攻礼、創(chuàng)建FormServlet,用于生成Token(令牌)和跳轉到form.jsp頁面
package xdp.gacl.session;
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 FormServlet extends HttpServlet {
? ? private static final long serialVersionUID = -884689940866074733L;
? ? public void doGet(HttpServletRequest request, HttpServletResponse response)
? ? ? ? ? ? throws ServletException, IOException {
? ? ? ? String token = TokenProccessor.getInstance().makeToken();//創(chuàng)建令牌
? ? ? ? System.out.println("在FormServlet中生成的token:"+token);
? ? ? ? request.getSession().setAttribute("token", token);? //在服務器使用session保存token(令牌)
? ? ? ? request.getRequestDispatcher("/form.jsp").forward(request, response);//跳轉到form.jsp頁面
? ? }
? ? public void doPost(HttpServletRequest request, HttpServletResponse response)
? ? ? ? ? ? throws ServletException, IOException {
? ? ? ? doGet(request, response);
? ? }
}
2栗柒、在form.jsp中使用隱藏域來存儲Token
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>form表單</title>
</head>
<body>
? ? <form action="${pageContext.request.contextPath}/servlet/DoFormServlet" method="post">
? ? ? ? <%--使用隱藏域存儲生成的token--%>
? ? ? ? <%--
? ? ? ? ? ? <input type="hidden" name="token" value="<%=session.getAttribute("token") %>">
? ? ? ? --%>
? ? ? ? <%--使用EL表達式取出存儲在session中的token--%>
? ? ? ? <input type="hidden" name="token" value="${token}"/>
? ? ? ? 用戶名:<input type="text" name="username">
? ? ? ? <input type="submit" value="提交">
? ? </form>
</body>
</html>
3礁扮、DoFormServlet處理表單提交
package xdp.gacl.session;
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 {
? ? public void doGet(HttpServletRequest request, HttpServletResponse response)
? ? ? ? ? ? ? ? throws ServletException, IOException {
? ? ? ? ? ? boolean b = isRepeatSubmit(request);//判斷用戶是否是重復提交
? ? ? ? ? ? if(b==true){
? ? ? ? ? ? ? ? System.out.println("請不要重復提交");
? ? ? ? ? ? ? ? return;
? ? ? ? ? ? }
? ? ? ? ? ? request.getSession().removeAttribute("token");//移除session中的token
? ? ? ? ? ? System.out.println("處理用戶提交請求!瞬沦!");
? ? ? ? }
? ? ? ? /**
? ? ? ? * 判斷客戶端提交上來的令牌和服務器端生成的令牌是否一致
? ? ? ? * @param request
? ? ? ? * @return
? ? ? ? *? ? ? ? true 用戶重復提交了表單
? ? ? ? *? ? ? ? false 用戶沒有重復提交表單
? ? ? ? */
? ? ? ? private boolean isRepeatSubmit(HttpServletRequest request) {
? ? ? ? ? ? String client_token = request.getParameter("token");
? ? ? ? ? ? //1太伊、如果用戶提交的表單數(shù)據(jù)中沒有token,則用戶是重復提交了表單
? ? ? ? ? ? if(client_token==null){
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? }
? ? ? ? ? ? //取出存儲在Session中的token
? ? ? ? ? ? String server_token = (String) request.getSession().getAttribute("token");
? ? ? ? ? ? //2逛钻、如果當前用戶的Session中不存在Token(令牌)僚焦,則用戶是重復提交了表單
? ? ? ? ? ? if(server_token==null){
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? }
? ? ? ? ? ? //3、存儲在Session中的Token(令牌)與表單提交的Token(令牌)不同绣的,則用戶是重復提交了表單
? ? ? ? ? ? if(!client_token.equals(server_token)){
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? }
? ? ? ? ? ? return false;
? ? ? ? }
? ? public void doPost(HttpServletRequest request, HttpServletResponse response)
? ? ? ? ? ? throws ServletException, IOException {
? ? ? ? doGet(request, response);
? ? }
}