spring boot 重复提交
package com.future.interceptor; import javax.servlet.http.HttpServletRequest; import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import com.baoqilai.scp.web.RestResultGenerator;
import com.future.shiro.ShiroUtils;
import com.google.common.cache.Cache; @Aspect
@Component
public class NoRepeatSubmitAop { private static final Logger logger = LoggerFactory.getLogger(NoRepeatSubmitAop.class); @Autowired
private Cache<String, Integer> cache; @Around("execution(* com.future.controller.*.*.*(..))&& @annotation(nos)")
public Object arround(ProceedingJoinPoint pjp, NoRepeatSubmit nos) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
String sessionId = ShiroUtils.getSession().getId().toString();
HttpServletRequest request = attributes.getRequest();
String key = sessionId + "-" + request.getServletPath();
if (cache.getIfPresent(key) != null) {
logger.error("重复提交");
return RestResultGenerator.genErrorResult("重复请求,请稍后再试");
}
// 如果是第一次请求,就将 key 当前对象压入缓存中
cache.put(key, 0);
try {
return pjp.proceed();
} catch (Throwable throwable) {
logger.error("验证重复提交时出现未知异常!");
return RestResultGenerator.genErrorResult("验证重复提交时出现未知异常!");
} finally {
cache.invalidate(key);
} } }
package com.future.interceptor; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @功能描述 防止重复提交标记注解
* @author Administrator
*
*/
@Target(ElementType.METHOD) // 作用到方法上
@Retention(RetentionPolicy.RUNTIME) // 运行时有效
public @interface NoRepeatSubmit { }
package com.future.config; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder; @Configuration
public class UrlCache { @Bean
public Cache<String, Integer> getCache() {
// return CacheBuilder.newBuilder().expireAfterWrite(2L, TimeUnit.SECONDS).build();// 缓存有效期为2秒
return CacheBuilder.newBuilder().build();// 不设置缓存有效期
}
}
@RequestMapping(value = "/test", method = RequestMethod.POST)
@NoRepeatSubmit
public RestResult test() {
int res=6;
if(res>0){
return RestResultGenerator.genSuccessResult();
}
return RestResultGenerator.genErrorResult("核单失败");
}
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>24.0-jre</version>
</dependency>
来自:https://www.jianshu.com/p/09c6b05b670a
https://blog.csdn.net/memmsc/article/details/80837996 分布式参考
spring boot 重复提交的更多相关文章
- spring boot 开发 提交form表单出错
提交表单时,字段有的没有值,springboot 会报错. org.springframework.validation.BindException: org.springframework.vali ...
- Spring boot POST 提交错误 Request header is too large
解决方法 application.yml server: # 单位 KB max-http-header-size: 100000 java.lang.IllegalArgumentException ...
- spring boot 学习(七)小工具篇:表单重复提交
注解 + 拦截器:解决表单重复提交 前言 学习 Spring Boot 中,我想将我在项目中添加几个我在 SpringMVC 框架中常用的工具类(主要都是涉及到 Spring AOP 部分知识).比如 ...
- Spring Boot (一) 校验表单重复提交
一.前言 在某些情况下,由于网速慢,用户操作有误(连续点击两下提交按钮),页面卡顿等原因,可能会出现表单数据重复提交造成数据库保存多条重复数据. 存在如上问题可以交给前端解决,判断多长时间内不能再次点 ...
- spring boot 防止重复提交
服务器端实现方案:同一客户端在2秒内对同一URL的提交视为重复提交 上代码吧 pom.xml <?xml version="1.0" encoding="UTF-8 ...
- Spring Boot 如何防止重复提交?
Java技术栈 www.javastack.cn 优秀的Java技术公众号 在传统的web项目中,防止重复提交,通常做法是:后端生成一个唯一的提交令牌(uuid),并存储在服务端.页面提交请求携带这个 ...
- Spring MVC拦截器+注解方式实现防止表单重复提交
原理:在新建页面中Session保存token随机码,当保存时验证,通过后删除,当再次点击保存时由于服务器端的Session中已经不存在了,所有无法验证通过. 注,如果是集群的方式,则需要将token ...
- Spring MVC实现防止表单重复提交(转)
Spring MVC拦截器+注解方式实现防止表单重复提交
- Spring MVC防止数据重复提交
现实开发中表单重复提交的例子很多,就包括手上这个门户的项目也有这种应用场景,用的次数多,但是总结,这还是第一次. 一.基本原理 使用token,给所有的url加一个拦截器,在拦截器里面用java的UU ...
随机推荐
- 使用 windsor 实现IOC 和 AOP
代码很简单,不多说. 对于拦截,windsor 使用动态代理的方式,即生成继承类的方式来实现的,因此无法拦截private 方法,因为无法在继承类中看见private方法. using System; ...
- thinkphp5操作redis系列教程】列表类型之lRange,lGetRange
<?php namespace app\admin\controller; use think\cache\driver\Redis; use think\Controller; use \th ...
- python 如何自动发送测试报告
首先,下载HTMLTestRuner.py文件. 源地址:http://tungwaiyip.info/software/HTMLTestRunner.html ,其次:把下载好的HTMLTestRu ...
- I/O复用select 使用简介
一:五种I/O模型区分: 1.阻塞I/O模型 最流行的I/O模型是阻塞I/O模型,缺省情形下,所有套接口都是阻塞的.我们以数据报套接口为例来讲解此模型(我们使用UDP而不是TCP作为例子的原 ...
- 使用U盘或在本地电脑作为git远程仓库进行托管
情景描述: 当有两台电脑需要共同维护一段代码,其中一台电脑不希望(或者不能)通过网络的方式进行访问git仓库(即不使用github),那么可以使用U盘作为介质将其作为远程仓库,或者使用局域网中一台电脑 ...
- PAT_A1016#Phone Bills
Source: PAT A1016 Phone Bills (25 分) Description: A long-distance telephone company charges its cust ...
- 【AI图像识别一】人脸识别测试探索
****************************************************************************** 本文主要介绍AI能力平台的人脸识别技术的测 ...
- 重大利好,Dubbo 3.0要来了。
关于Dubbo的好消息,2018年1月8日,Dubbo创始人之一梁飞在Dubbo交流群里透露了Dubbo 3.0正在开工的重大消息. Dubbo是阿里开源的分布式框架,已经多年停止更新处于半死不活状态 ...
- 高程(三)----数组Array
一.数组的创建 var arrayObj = new Array(); //创建一个数组 var arrayObj = new Array([size]); //创建一个数组并指定长度,注意不是上 ...
- Selenium3 + Python3自动化测试系列八——警告框处理和下拉框选择
警告框处理 在WebDriver中处理JavaScript所生成的alert.confirm以及prompt十分简单,具体做法是使用 switch_to.alert 方法定位到 alert/confi ...