表单重复提交
1.表单重复提交情况:
表单提交到一个Servlet,而Servlet又通过请求转发的方式响应一个JSP页面,此时地址栏还保留的servlet 的路径,此时刷新会导致重复提交
在相应页面没有到达时点击,会导致
点击返回再次提交
2.点击返回,刷新再次提交原表单 不是重复提交
3.解决:
在表单中做一个标记,提交到servlet时 ,检查标记是否存在和预设标记是否一致,若一致则受理请求,并销毁标记,若不一致没有标记,则相应提示页面
1>建立一个隐藏的input 放置token 行不通 没有方法清除固定的参数
2>request 中也不行,应为表单页面刷新后request已经被销毁,再提交是一个新的request
3>实现
>在原表单页面生成一个token
>在原表单页面把token值放入session属性中
>在原表单页面把token值放入隐藏域中
>在目标的Servlet中:获取session 和 隐藏与中的token值 比较两个值是否一致 如果一直手里请求 并把session中token清楚 ,若不同提示重复提交
<% String tokenValue = new Date().getTime() + ""; session.setAttribute("token",tokenValue); %> <form action="<%=request.getContextPath()%>/tokenServlet" method="post"> <input type="hidden" name="token" value="<%=tokenValue %>"/> name:<input type="text" name="name"/> <input type="submit" value="Submit"/> </form>
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { Thread.sleep(2000); } catch (Exception e) { e.printStackTrace(); } HttpSession session = request.getSession(); Object token = session.getAttribute("token"); String tokenValue = request.getParameter("token"); System.out.println(token); System.out.println(tokenValue); if(token != null && token.equals(tokenValue)) { session.removeAttribute("token"); }else { response.sendRedirect(request.getContextPath()+"/form/token.jsp"); return; } String name = request.getParameter("name"); System.out.print("name:"+name); //request.getRequestDispatcher("form/success.jsp").forward(request, response); response.sendRedirect(request.getContextPath()+"/form/success.jsp"); }
JAVA源码
TokenProcessor.java
重定向
response.sendRedirect(request.getContextPath() + "/book/step-2.jsp");
转发
request.getRequestDispatcher("step-2.jsp").forward(request, response);