前提 : 做web 开发避免不了,表单重复提交产生脏数据的情景,
原理: 以一个注册业务例,如果页面提交按钮没有受到控制,在快速连续点击提交时,会提交生成多条注册申请信息
解决方案为: 在注册页面刚打开的时候 给定一个随机数字,标识页面(存储在session) , 在程序后台通过校验随机数字来判断是否同一个页面多次提交的注册申请
代码事例: 由于可能在项目的多个地方都会使用,故提出到公共的 .tag
-------------------Constants.java---------------
/** 表单token的session名称*/ public static final String FORM_TOKEN_SESSION_NAME = "__BSP_FORM_TOKEN";
-------------formToken.tag-----------------------
<%@tag import="com.bsteel.common.Constants"%>
<%@tag import="java.util.UUID"%>
<%@ include file="/pages/common/tag.jsp"%>
<%
request.getSession(false).setAttribute(Constants.FORM_TOKEN_SESSION_NAME, UUID.randomUUID().toString());
%>
<input type="hidden" id="formToken" name="formToken" value="<%=session.getAttribute(Constants.FORM_TOKEN_SESSION_NAME)%>"/>
--------------------tag.jsp--------------------
<%@ taglib prefix="bsp" tagdir="/WEB-INF/tags" %>----------------jsp页面如何使用刚刚定义的formToken.jsp--------------
form表单内:
<bsp:formToken ></bsp:formToken>
---------------------java 后台的校验(写公共方法)-------------------------------------------------
/** * 检测表单是否重复提交 * @param request HTTP请求 * @return 重复提交则返回true,否则false */ public void isRepeatSubmit() { HttpServletRequest request = RequestHolder.getRequest(); String serverToken = (String) request.getSession(false).getAttribute(Constants.FORM_TOKEN_SESSION_NAME); if (StringUtils.isEmpty(serverToken)) { throw new CommonException("请勿重复提交"); } String clientToken = request.getParameter("formToken"); if (StringUtils.isEmpty(clientToken)) { throw new CommonException("表单token丢失"); } if (!clientToken.equals(serverToken)) { throw new CommonException("请勿重复提交"); } request.getSession().removeAttribute(Constants.FORM_TOKEN_SESSION_NAME); }