最近在本地开发测试的时候,遇到一个表单重复提交的现象。
因为网络延迟的问题,我点击了两次提交按钮,数据库里生成了两条记录。其实这种现象以前也有遇到过,一般都是提交后把按钮置灰,无法再次提交,这是很常见的客户端处理的方式。
但是这不是从根本上解决问题,虽然客户端解决了多次提交的问题,但是接口中依旧存在着问题。假设我们不是从客户端提交,而是被其他的系统调用,当遇到网络延迟,系统补偿的时候,还会遇到这种问题
1、通过session中的token验证
- 初始化页面时生成一个唯一token,将其放在页面隐藏域和session中
- 拦截器拦截请求,校验来自页面请求中的token与session中的token是否一致
- 判断,如果一致则提交成功并移除session中的token,不一致则说明重复提交并记录日志
步骤1:创建自定义注解
1 | java复制代码@Target(ElementType.METHOD) |
步骤2:创建自定义拦截器(@slf4j是lombok的注解)
1 | java复制代码@Slf4j |
步骤3:将自定义拦截器添加到配置文件
1 | xml复制代码<mvc:interceptor> |
使用案例
1 | java复制代码 //save = true 用于生成token |
jsp页面隐藏域添加token
1 | html复制代码 <input type="hidden" name="token" value="${sessionScope.token}"> |
2、通过当前用户上一次请求的url和参数验证重复提交
- 拦截器拦截请求,将上一次请求的url和参数和这次的对比
- 判断,是否一致说明重复提交并记录日志
步骤1:创建自定义注解
1 | java复制代码@Target(ElementType.METHOD) |
步骤2:创建自定义拦截器
1 | java复制代码public class SameUrlDataInterceptor extends HandlerInterceptorAdapter { |
步骤3:将自定义拦截器添加到配置文件
1 | xml复制代码<mvc:interceptor> |
使用案例
1 | java复制代码 //在controller层使用 @SameUrlData 注解即可 |
本文转载自: 掘金