码迷,mamicode.com
首页 > 其他好文 > 详细

表单重复提交问题

时间:2020-06-26 12:23:08      阅读:59      评论:0      收藏:0      [点我收藏+]

标签:过程   页面   inf   BMI   lan   没有   技术   ram   parameter   

表单重复提交问题

1.表单重复提交的根本原因

  • 没有完整的进行 一次请求页面 —> 提交页面的过程 而完成数据提交

技术图片

2.造成重复提交的现象

  1. 由于服务器缓慢或者网速原因,重复点击按钮
  2. 已经提交成功,刷新成功页面
  3. 提交成功后,通过回退,再次点击提交按钮

3.解决方案

从根本原因入手:没有进行完整的两次请求

第一次:先请求表单页面

第二次:再提交表单请求

解决方案:必须执行第二次之前,必须执行第一次。

这里的原理 和 验证码的原理是类似的

通过口令(token)验证 :请求产生一个随机数 和 Session中的随机数 比较

若相同 进入后面代码逻辑 消除本次Session的随机数(口令使用一次)

进入表单页面时要 请求的Servlet中的service方法

该方法生成一个随机数 放入Session中

再放入Request中 用于跳转表单页面时 随机数的传递

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String token = UUID.randomUUID().toString();
		// 将token放进 Session中   后面进行验证
		req.getSession().setAttribute("TOKEN_IN_SESSION", token);
		// 将token值放进Request请求中  用于给jsp页面的隐藏域token设值
		req.setAttribute("token", token);
		// 跳到jsp页面  
		req.getRequestDispatcher("/repeatsubmit/transfrom.jsp").forward(req, resp);
	}

表单页面(transfrom.jsp):

这里有一个隐藏input元素 用来存放上面Servlet传过来的随机数

<body>
		<form action="/repeatsubmit" method="POST">
			转账:<input type="text" name = "money" required="required"><br>
			   	 <input type="hidden" name = "token"  value=${token}><br>
			<input type="submit"  value="我要转账">
		</form>
		
</body>

当表单点击提交按钮后 会交给一个/repeatsubmit的Servlet去处理

该Servlet的service方法: 将表单中的隐藏的随机数和Session的随机进行比较

若一样 则表示成功提交 并销毁Session中的随机数

如果现在刷新页面等重复提交操作,表单的随机数还是原来的 而Session中的随机数是null

一比较,就会进入重复提交的代码逻辑处理操作

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String tokenInRequest = req.getParameter("token");
		String tokenInSession = (String) req.getSession().getAttribute("TOKEN_IN_SESSION");
		
		if (tokenInRequest.equals(tokenInSession)) {
			// 相等 则销毁Session  口令只使用一次
			req.getSession().removeAttribute("TOKEN_IN_SESSION");
			
			String money = req.getParameter("money");
			System.out.println("转出:" + money);
			
			resp.setContentType("text/html;charset=utf-8");
			PrintWriter out = resp.getWriter();
			out.write("转账成功!");
		}else {
			System.out.println("已重复提交!");
		}
	}

表单重复提交问题

标签:过程   页面   inf   BMI   lan   没有   技术   ram   parameter   

原文地址:https://www.cnblogs.com/yhnCoder/p/13194147.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!