博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AOP + Redis实现防止表单重复提交(注解方式)
阅读量:3926 次
发布时间:2019-05-23

本文共 3267 字,大约阅读时间需要 10 分钟。

  • 引入SpringAOP
org.springframework.boot
spring-boot-starter-aop
  • 配置redis,并创建redis工具类

               redis配置此处略过

@Service@Slf4jpublic class RedisService {    @Resource    private StringRedisTemplate stringRedisTemplate;    public boolean existKey(String key) {        log.debug("existKey().params:" + key);        return stringRedisTemplate.hasKey(key);    }    public Boolean delKey(String key) {        log.debug("delKey().params:" + key);        Boolean delete = stringRedisTemplate.delete(key);        return delete;    }    public boolean addString(String key, String value) {        BoundValueOperations
ops = stringRedisTemplate.boundValueOps(key); try { ops.set(value); return true; } catch (Exception e) { log.error("redis添加异常." + e.getMessage(), e); e.printStackTrace(); return false; } } public boolean addString(String key, String value, long timeout, TimeUnit timeUnit) { BoundValueOperations
ops = stringRedisTemplate.boundValueOps(key); try { ops.set(value, timeout, timeUnit); return true; } catch (Exception e) { log.error("redis添加异常." + e.getMessage(), e); e.printStackTrace(); return false; } }}
  • 创建注解
@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface FormLock {    /**     * 指定时间内不可重复提交,单位毫秒     * @return     */    long timeout() default 3000;}
  • 创建AOP环绕通知处理类
@Slf4j@Aspect@Componentpublic class FormLockAspect {    @Autowired    private RedisService redisService;    @Pointcut("@annotation(com.wetran.codex.business.avoid_repetition.AFormLock)")    public void reqLock() {    }    /**     * @param point     */    @Around("reqLock()")    public Object constructionSite(ProceedingJoinPoint point) throws Throwable {        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();        //获取注解        MethodSignature signature = (MethodSignature) point.getSignature();        Method method = signature.getMethod();        //目标类、方法        String className = method.getDeclaringClass().getName();        String methodName = method.getName();        //由于使用方法名+用户ID创建的Key,,,必须要有用户id参数        Long userId = Long.parseLong(request.getParameter("id"));        log.info("防止表单重复提交类:{}. 方法:{}.用户ID:{}.", className, methodName, userId);        String key = RedisConstants.BLACKlIST_LOCK_KEY + methodName + ":" + userId;        FormLock formLock = method.getAnnotation(FormLock.class);        long timeout = formLock.timeout();        if (timeout < 0) {            //过期时间3000毫秒            timeout = 3000;        }        //校验该方法该用户的key是否存在,存在直接返回错误        if (redisService.existKey(key)) {            return RespUtils.fail("请勿重复提交");        }        boolean b = redisService.addString(key, DateUtils.getNow(), timeout, TimeUnit.MILLISECONDS);        log.info("创建锁结果:{}. key:{}.", b, key);        //执行方法        Object object = point.proceed();        //整理施工现场        Boolean aBoolean = redisService.delKey(key);        log.info("删除redis锁结果:{}.", aBoolean);        return object;    }}

redis有效时间根据自身业务需求进行调整即可

在需要防止表单重复提交的方法上添加@FormLock注解即可,可根据不同方法指定相应的有效时间

转载地址:http://gncgn.baihongyu.com/

你可能感兴趣的文章
sql练习-获取所有员工当前的manager,如果当前的manager是自己的话结果不显示,当前表示to_date='9999-01-01'。
查看>>
sql练习--查找所有员工的last_name和first_name以及对应的dept_name,也包括暂时没有分配部门的员工
查看>>
Transformer-based Object Re-Identification论文解读
查看>>
Android BLE开发
查看>>
Java内部类详解
查看>>
Android系统架构初探
查看>>
Android开发常见面试题类型
查看>>
2017美团校招安卓岗
查看>>
YUV基础知识《转载》
查看>>
C语言动态申请内存
查看>>
cmake万能模板
查看>>
让你不再害怕指针——C指针详解
查看>>
十张图解释机器学习的基本概念
查看>>
端口复用及其实现分析[Google Patch]
查看>>
红黑树:自平衡的二叉查找树
查看>>
回收站功能在 Linux 中的实现
查看>>
数据包头分析---网络字节序与主机字节序
查看>>
linux sh/bash 编程常用
查看>>
《Debug Hacks》和调试技巧
查看>>
x86寄存器和栈帧
查看>>