Java中避免表單重複提交,java表單重複提交

來源:互聯網
上載者:User

Java中避免表單重複提交,java表單重複提交

表單的重複提交: 沒有完整的進行一次,先請求表單頁面->再提交表單過程而完成資料提交

造成的根本原因: 沒有完整的進行一次,先請求表單頁面->再提交表單過程.

造成重複提交的現象:

  • 注意:回退後,重新整理表單頁面,重新再提交,這時,不是重複提交,而是發送新的請求,在Firefox下,重複提交到同一個地址的操作無效.

案例:

 1 @WebServlet("/trans") 2 public class TransferServlet extends HttpServlet{ 3     private static final long serialVersionUID = 1L; 4      5     protected void service(HttpServletRequest req, HttpServletResponse resp) 6             throws ServletException, IOException { 7         req.setCharacterEncoding("UTF-8"); 8         resp.setContentType("text/html;charset=UTF-8"); 9         PrintWriter out = resp.getWriter();10         String money = req.getParameter("money");11         //通過睡眠,類比網路延遲12         try {13             Thread.sleep(3000);14         } catch (InterruptedException e) {15             e.printStackTrace();16         }17         System.out.println("轉出金額:"+money);18         out.print("轉出金額:"+money);    19     }20 }

在狂點之下,會發現,jsp頁面不會有變化,但是通過背景列印輸出可以看到,會不停地輸出,說明一直在執行

解決方案:

保證提交保證之前,就必須先請求表單介面,原理和驗證碼一樣.----令牌機制

在第一次請求的時候,請求到表單介面時,建立一個令牌,當點擊轉賬,發送請求的時候,帶上這個令牌,發送到下一個介面,在servlet中對這個令牌進行驗證,這個令牌在session中一份,在表單中一份,相等說明表單正確,並且把這個session中的令牌銷毀掉.

在jsp頁面中的代碼

 1      <% 2             //建立令牌 3             String token = java.util.UUID.randomUUID().toString(); 4             //存在session中一份,以後做判斷 5             session.setAttribute("TOKEN_IN_SESSION", token); 6         %> 7          8         <h3>轉賬介面</h3> 9         <form action="/trans" method="post">10             <input type="hidden" name="token" value="<%=token%>"/>11             轉賬金額:<input type="text" name="money" min="1" required /><br/>12             <input type="submit" value="轉賬" />13         </form>

在TransferServlet中的代碼

 1 @WebServlet("/trans") 2 public class TransferServlet extends HttpServlet{ 3     private static final long serialVersionUID = 1L; 4      5     protected void service(HttpServletRequest req, HttpServletResponse resp) 6             throws ServletException, IOException { 7         req.setCharacterEncoding("UTF-8"); 8         resp.setContentType("text/html;charset=UTF-8"); 9         PrintWriter out = resp.getWriter();10         //擷取表單中的token值11         String token = req.getParameter("token");12         //擷取session中的token值13         String sessionToken = (String) req.getSession().getAttribute("TOKEN_IN_SESSION");14         //session中的token容易為空白,因為session中的token是需要被銷毀的15         16         if (token.equals(sessionToken)) {17             //說明令牌相同18             req.getSession().removeAttribute("TOKEN_IN_SESSION");19             String money = req.getParameter("money");20             System.out.println("轉出金額:"+money);21             out.print("轉出金額:"+money);22             //最後銷毀session中的令牌23         }24         //如果令牌不同說明就是重複提交,不能提交25     }26 }

 然後呢,為了不想在jsp檔案中出現Java代碼,把令牌的建立並跳轉放在另一個servlet中

 1 @WebServlet("/transfer") 2 public class CopyOfTransferServlet extends HttpServlet{ 3     private static final long serialVersionUID = 1L; 4      5     protected void service(HttpServletRequest req, HttpServletResponse resp) 6             throws ServletException, IOException { 7         //建立令牌,並跳轉到submit.jsp 8         String token = UUID.randomUUID().toString(); 9         System.out.println(token);10         req.getSession().setAttribute("TOKEN_IN_SESSION", token);11         req.setAttribute("token", token);12         req.getRequestDispatcher("/views/repeatsubmit/submit.jsp").forward(req, resp);13         14     }15 }

 

此時jsp檔案中就是這個樣子

1      <h3>轉賬介面</h3>2         <form action="/trans" method="post">3             <input type="hidden" name="token" value="${token }"/>4             轉賬金額:<input type="text" name="money" min="1" required /><br/>5             <input type="submit" value="轉賬" />6         </form>

比上面的乾淨了很多,更加整齊,但是還是感覺不好,因為如果在其他地方需要用到,還需要在建立令牌,校正令牌,刪除令牌,因此就抽取出來做一個工具類

   TokenUtil.java
1 //令牌的工具類 2 //建立令牌 3 //校正令牌 4 //銷毀令牌 5 public class TokenUtil { 6 private final static String TOKEN_IN_SESSION = "TOKEN_IN_SESSION"; 7 public static void savaToken(HttpServletRequest req) { 8 String token = UUID.randomUUID().toString(); 9 System.out.println(token);10 req.getSession().setAttribute(TOKEN_IN_SESSION, token);11 req.setAttribute("token", token);12 }13 14 public static boolean validateToken(HttpServletRequest req,15 String tokenInrequest) {16 //擷取session中的token值17 String sessionToken = (String) req.getSession().getAttribute(18 TOKEN_IN_SESSION);19 if (tokenInrequest.equals(sessionToken)) {20 req.getSession().removeAttribute(TOKEN_IN_SESSION);21 return true;22 }23 return false;24 }25 }

這樣就好了,使用者只需要調用這個工具類就好了,不需要再去寫建立令牌等一系列操作

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.