spring MVC 后台token防重复提交解决方案
看到公司有个部门提出了这个问题,补个粗略的解决方案。。。
1.编写拦截器
/**
* Description: 防止重复提交
*
* @Author liam
* @Create Date: 2018/3/9 9:22
*/
public class AvoidReSubmitIntercepter extends HandlerInterceptorAdapter { private static final String SPLIT_FLAG = "_";
private static final String AVOID_RE_SUBMIT_TOKEN_KEY = "identifier_token"; @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (checkAvoidReSubmitTokenOn(handler,AvoidReSubmitBehavior.Check)) {
//验证是否重复
if (checkIsRepeatSubmit(request)) {
//重复提交
return false;
}
}
return super.preHandle(request, response, handler);
} @Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
if (checkAvoidReSubmitTokenOn(handler,AvoidReSubmitBehavior.Create)) {
Random random = new Random();
String uuid = UUID.randomUUID().toString().replace(SPLIT_FLAG, String.valueOf(random.nextInt()));
String tokenValue = String.valueOf(System.currentTimeMillis());
String transferToken = uuid + SPLIT_FLAG + tokenValue;
request.setAttribute(AVOID_RE_SUBMIT_TOKEN_KEY, transferToken);
request.getSession(true).setAttribute(uuid, tokenValue);
}
super.postHandle(request, response, handler, modelAndView);
} /**
* Description: 是否开启防重规则
*
* @Author liam
* @Create Date: 2018/3/9 10:33
*/
private boolean checkAvoidReSubmitTokenOn(Object handler,AvoidReSubmitBehavior behavior) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method invokeMethod = handlerMethod.getMethod();
AvoidReSubmitToken avoidReSubmitToken = invokeMethod.getAnnotation(AvoidReSubmitToken.class);
if (avoidReSubmitToken != null && avoidReSubmitToken.behavior().equals(behavior)) {
return true;
}
return false; } private boolean checkIsRepeatSubmit(HttpServletRequest request) {
String clientToken = request.getParameter(AVOID_RE_SUBMIT_TOKEN_KEY);
if (StringUtils.isEmpty(clientToken)) {
clientToken = request.getParameter(AVOID_RE_SUBMIT_TOKEN_KEY);
if (StringUtils.isEmpty(clientToken)) {
return true;
}
}
String[] clientTokensDetail = StringUtils.split(clientToken, SPLIT_FLAG);
if (clientTokensDetail.length == ) {
String uuid = clientTokensDetail[];
String token = clientTokensDetail[];
//此处存在并发风险...阔以加锁处理
String serverToken = (String) request.getSession(true).getAttribute(uuid);
if (StringUtils.isNotEmpty(serverToken) && token.equals(serverToken)) {
request.getSession(true).removeAttribute(uuid);
return false;
}
}
return true;
}
}
提供开启规则的注解:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AvoidReSubmitToken { AvoidReSubmitBehavior behavior(); }
定义两种行为:
public enum AvoidReSubmitBehavior {
Create,
Check;
}
拦截器的配置:
<!-- 拦截器配置 -->
<mvc:interceptors>
<!-- 配置Token拦截器,防止用户重复提交数据 -->
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="liam.AvoidReSubmitIntercepter"/>
</mvc:interceptor>
</mvc:interceptors>
Java代码使用;
@AvoidReSubmitToken(behavior = AvoidReSubmitBehavior.Create)
@RequestMapping("test")
public String testPage() {
return "form/page";
}
@AvoidReSubmitToken(behavior = AvoidReSubmitBehavior.Check)
@RequestMapping("potHandler")
public String postHandler(){
return "ok";
}
页面代码:
<form id="" class="form-horizontal" action="${ctx}/postHandler" method="post">
......
<input type="hidden" name="token" value="${identifier_token}"/>
<!-- 注:name必须是identifier_token -->
......
</form>
其实该方案也可以验证提交数据是否有效,当然通常是把token放到只读的缓存了。。
伪代码。。没测试呢。。。
spring MVC 后台token防重复提交解决方案的更多相关文章
- SpringMVC后台token防重复提交解决方案
本文介绍如何使用token来防止前端重复提交的问题. 目录 1.思路 2.拦截器源码实现 3.注解源码 4.拦截器的配置 5.使用指南 6.结语 思路 1.添加拦截器,拦截需要防重复提交的请求 2.通 ...
- Spring MVC表单防重复提交
利用Spring MVC的过滤器及token传递验证来实现表单防重复提交. 创建注解 @Target(ElementType.METHOD) @Retention(RetentionPolicy.RU ...
- spring mvc防止表单重复提交的代码片段
1.定义一个token接口 package com.bigbigrain.token; import java.lang.annotation.Documented; import java.lang ...
- (亿级流量)分布式防重复提交token设计
大型互联网项目中,很多流量都达到亿级.同一时间很多的人在使用,而每个用户提交表单的时候都可能会出现重复点击的情况,此时如果不做好控制,那么系统将会产生很多的数据重复的问题.怎样去设计一个高可用的防重复 ...
- 架构设计 | 接口幂等性原则,防重复提交Token管理
本文源码:GitHub·点这里 || GitEE·点这里 一.幂等性概念 1.幂等简介 编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同.就是说,一次和多次请求某一个资源会产 ...
- 使用aop注解实现表单防重复提交功能
原文:https://www.cnblogs.com/manliu/articles/5983888.html 1.这里采用的方法是:使用get请求进入表单页面时,后台会生成一个tokrn_flag分 ...
- (九)Struts2 防重复提交
所有的学习我们必须先搭建好Struts2的环境(1.导入对应的jar包,2.web.xml,3.struts.xml) 第一节:重复提交示例演示 struts.xml <?xml version ...
- AJAX防重复提交的办法总结
最近的维护公司的一个代理商平台的时候,客服人员一直反映说的统计信息的时候有重复数据,平台一直都很正常,这个功能是最近新进的一个实习生同事写的功能,然后就排查问题人所在,发现新的这个模块的AJAX提交数 ...
- struts2学习(15)struts2防重复提交
一.重复提交的例子: 模拟一种情况,存在延时啊,系统比较繁忙啊啥的. 模拟延迟5s钟,用户点了一次提交,又点了一次提交,例子中模拟这种情况: 这样会造成重复提交: com.cy.action.St ...
随机推荐
- CentOS7系列--2.1CentOS7中安装配置NTP服务
CentOS7安装配置NTP服务 NTP服务是时间同步服务 1. 安装NTPd [root@centos7 ~]# yum install -y ntp [jack@centos7 ~]$ vi /e ...
- MySQL的索引与优化
写在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储100条记录.如果没有索引,查询将 ...
- linux 用户管理 groupadd、groupmod、groupdel、gpasswd
添加用户组groupadd [选项] 组名 /usr/sbin/groupadd执行权限:root一个用户可以属于多个所属组,但有一个缺省组,和用户名同名-g GID:指定组ID 修改用户组 grou ...
- Pig数据类型
基本类型 int.long.float.double.chararray.bytearray.datatime.boolean.biginteger.bigdecimal 复杂类型 map.tuple ...
- 外业数据采集平台(GPS+Android Studio+Arcgis for android 100.2.1)
外业数据采集平台 1. 综述 在室外,通过平板或者手机接收GPS坐标,实时绘制点.线.面数据,以便为后续进行海域监测.土地确权.地图绘图提供有效数据和依据. 2. 技术路线 Android studi ...
- 事件驱动模型 IO多路复用 阻塞IO与非阻塞IO select epool
一.事件驱动 1.要理解事件驱动和程序,就需要与非事件驱动的程序进行比较.实际上,现代的程序大多是事件驱动的,比如多线程的程序,肯定是事件驱动的.早期则存在许多非事件驱动的程序,这样的程序,在需要等待 ...
- 在线制作GIF图片项目愿景与范围
在线制作GIF图片项目愿景与范围 a. 业务需求 a.1 背景 在当今社会中,随着聊天软件和web网站的普及,原创动画制作越来越吸引人们的眼球,一个好的动态图片,可能就会为你的网站或本人赢得更多人的认 ...
- CCSUOJ评测系统——第三次scrum冲刺
1.小组成员 舒 溢 许嘉荣 唐 浩 黄欣欣 廖帅元 刘洋江 薛思汝 2.个人在小组第三次冲刺的任务及其完成情况描述. 本人在小组第三次冲刺的任务是负责代码的编写,其他人提需求和改进,代码是采用Git ...
- 课后作业week 5 —— 两款修图软件优势及创新分析
由于我平时没事也会修修照片什么的,也用过一些不同种类的修图软件,这次作业就选择了其中两款比较热门的软件进行分析. 说到手机修图app,很多人很容易想到“美图秀秀”,的确这款app在修图软件领域的确算的 ...
- [翻译] SCViewShaker
SCViewShaker https://github.com/rFlex/SCViewShaker About A highly configurable UIView category for s ...