Session机制三(表单的重复提交)

1.表单的重复提交的情况

  在表单提交到一个servlet,而servlet又通过请求转发的方式响应了一个JSP页面,这个时候地址栏还保留这servlet的那个路径,在响应页面点击刷新。

  在响应页面没有到达时,重复点击提交按钮。

  点击返回,再点击提交

  

2.如何避免重复提交

  在表单年中做一个标记,在提交到servlet时,检查标记是否与预定义的标记一致,若一致,则受理请求,并销毁标记,若不一致或没有标记,则直接响应提示信息,“重复提交”。

  

3.方法

  > 在原表单页面, 生成一个随机值 token
  > 在原表单页面, 把 token 值放入 session 属性中
  > 在原表单页面, 把 token 值放入到 隐藏域 中.

  > 在目标的 Servlet 中: 获取 session 和 隐藏域 中的 token 值
  > 比较两个值是否一致: 若一致, 受理请求, 且把 session 域中的 token 属性清除
  > 若不一致, 则直接响应提示页面: "重复提交"

4.index.jsp

 1 <%@page import="java.util.Date"%>
 2 <%@ page language="java" contentType="text/html; charset=utf-8"
 3     pageEncoding="utf-8"%>
 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 5 <html>
 6 <head>
 7 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 8 <title>Insert title here</title>
 9 </head>
10 <body>
11     <%
12             String tokenValue=new Date().getTime()+"";
13             session.setAttribute("token", tokenValue);
14     %>
15     <form action="<%=request.getContextPath()%>/tokenServlet" method="post">
16         <!-- 隐藏域 -->
17         <input type="hidden" name="token" value="<%=tokenValue%>"/>
18         name:<input type="text" name="name"/>        
19         <input type="submit" value="Submit"/>
20     </form>
21 </body>
22 </html>

5.TokenServlet.java

 1 import java.io.IOException;
 2 import javax.servlet.ServletException;
 3 import javax.servlet.annotation.WebServlet;
 4 import javax.servlet.http.HttpServlet;
 5 import javax.servlet.http.HttpServletRequest;
 6 import javax.servlet.http.HttpServletResponse;
 7 import javax.servlet.http.HttpSession;
 8 
 9 @WebServlet("/tokenServlet")
10 public class TokenServlet extends HttpServlet {
11     private static final long serialVersionUID = 1L;
12 
13     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
14         try {
15             Thread.sleep(3000);
16         }catch(Exception e) {
17             e.printStackTrace();
18         }
19         String name=request.getParameter("name");
20         System.out.println("name="+name);
21         /**
22          * 使用session消除表单的重复提交
23          */
24         HttpSession session=request.getSession();
25         Object token=session.getAttribute("token");
26         String tokenValue=request.getParameter("token");
27         System.out.println("token="+token);
28         System.out.println("tokenValue="+tokenValue);
29         if(token!=null&&token.equals(tokenValue)) {
30             session.removeAttribute("token");
31         }else {
32             response.sendRedirect(request.getContextPath()+"/path/token.jsp");
33             return;
34         }
35         request.getRequestDispatcher("/path/sucess.jsp").forward(request, response);
36     }
37 
38 }

6.success.jsp

 1 <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
 2     pageEncoding="ISO-8859-1"%>
 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 4 <html>
 5 <head>
 6 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
 7 <title>Insert title here</title>
 8 </head>
 9 <body>
10     <h1>success page</h1>
11 </body>
12 </html>

7.token.jsp

 1 <%@ page language="java" contentType="text/html; charset=utf-8"
 2     pageEncoding="utf-8"%>
 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 4 <html>
 5 <head>
 6 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
 7 <title>Insert title here</title>
 8 </head>
 9 <body>
10     <h2>sorry,已经提交过了</h2>
11 </body>
12 </html>

8.效果

  

  

原文地址:https://www.cnblogs.com/juncaoit/p/7476547.html