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.效果