表单重复提交解决方案

什么是token
token其实就是一个令牌,具有随机性,类似于sessionId。
在对接一些第三方平台的时候,为了能够保证数据安全性,通常会使用一些令牌进行交互。
from.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>


  
    Form表单
  
  
  
      
用户名:

处理类:

WebServlet("/DoFormServlet")
public class DoFormServlet extends HttpServlet {

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		req.setCharacterEncoding("UTF-8");
		String userName = req.getParameter("userName");
		try {
			Thread.sleep(300);
		} catch (Exception e) {
			// TODO: handle exception
		}
		System.out.println("往数据库插入数据...."+userName);
		resp.getWriter().write("success");
	}
}

造成表单重复提交的原因:
场景一: 在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交。
场景二:按钮导致表单重复提交
场景三:按钮回退到表单页面后进行再次提交
场景四:用户提交表单后,点击浏览器的【后退】按钮回退到表单页面后进行再次提交
解决方案
使用javascript 解决
 既然存在上述所说的表单重复提交问题,那么我们就要想办法解决,比较常用的方法是采用JavaScript来防止表单重复提交,具体做法如下:
修改form.jsp页面,添加如下的JavaScript代码来防止表单重复提交

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>



Form表单




	
用户名:

除了用这种方式之外,经常见的另一种方式就是表单提交之后,将提交按钮设置为不可用,让用户没有机会点击第二次提交按钮,代码如下:

function dosubmit(){
    //获取表单提交按钮
    var btnSubmit = document.getElementById("submit");
    //将表单提交按钮设置为不可用,这样就可以避免用户再次点击提交按钮
    btnSubmit.disabled= "disabled";
    //返回true让表单可以正常提交
    return true;
}

** 使用后端提交解决**
 对于【场景二】和【场景三】导致表单重复提交的问题,既然客户端无法解决,那么就在服务器端解决,在服务器端解决就需要用到session了。
  具体的做法:在服务器端生成一个唯一的随机标识号,专业术语称为Token(令牌),同时在当前用户的Session域中保存这个Token。然后将Token发送到客户端的Form表单中,在Form表单中使用隐藏域来存储这个Token,表单提交的时候连同这个Token一起提交到服务器端,然后在服务器端判断客户端提交上来的Token与服务器端生成的Token是否一致,如果不一致,那就是重复提交了,此时服务器端就可以不处理重复提交的表单。如果相同则处理表单提交,处理完后清除当前用户的Session域中存储的标识号。
在下列情况下,服务器程序将拒绝处理用户提交的表单请求:
1.存储Session域中的Token(令牌)与表单提交的Token(令牌)不同。
2.当前用户的Session中不存在Token(令牌)。
3.用户提交的表单数据中没有Token(令牌)。
转发处理类:

@WebServlet("/ForwardServlet")
public class ForwardServlet extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		req.getSession().setAttribute("sesionToken", TokenUtils.getToken());
		req.getRequestDispatcher("form.jsp").forward(req, resp);
	}
}

转发页面:

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>



Form表单




	
用户名:

处理类:

@WebServlet("/DoFormServlet")
public class DoFormServlet extends HttpServlet {
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		req.setCharacterEncoding("UTF-8");
		boolean flag = isFlag(req);
		if (!flag) {
			resp.getWriter().write("已经提交...");
			System.out.println("数据已经提交了..");
			return;
		}
		String userName = req.getParameter("userName");
		try {
			Thread.sleep(300);
		} catch (Exception e) {
			// TODO: handle exception
		}
		System.out.println("往数据库插入数据...." + userName);
		resp.getWriter().write("success");
	}

	public boolean isFlag(HttpServletRequest request) {
		HttpSession session = request.getSession();
		String sesionToken = (String) session.getAttribute("sesionToken");
		String token = request.getParameter("token");
		if (!(token.equals(sesionToken))) {
			return false;
		}
		session.removeAttribute("sesionToken");
		return true;
	}
}

你可能感兴趣的:(java基础)