• java使用redis防止表单重复提交,点击过快的问题


    思路也很简单,用户访问某一接口一般都有唯一标识,前缀+唯一标识+uri存入redis,为了防止死锁问题,一定要设置该key的有效期我这里是3秒,重复点击间隔为1秒,用户点击没有key则存入redis,如果存在则判断时间是否小于间隔时间,小于则返回错误提示,大于则重新设置该key到redis。

    上代码!!!

    import com.sjyf.gym.exception.BusinessException;
    import com.sjyf.gym.utils.HttpContextUtils;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.lang3.StringUtils;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.stereotype.Component;
    
    import javax.annotation.Resource;
    import java.util.Objects;
    import java.util.concurrent.TimeUnit;
    
    @Slf4j
    @Aspect
    @Component
    public class RepeatSubmitAspect {
    
        private static final String PREFIX = "repeat:user:";
    
        /**
         * 防重复点击间隔时间(毫秒)
         */
        private static final long REPEAT_TIME = 1000;
    
        @Resource
        private RedisTemplate redisTemplate;
    
        /**
         * 切入点
         */
        @Pointcut("execution(* com.sjyf.gym.*.controller.*.*.*(..))")
        public void repeat(){}
    
        /**
         * 方法执行前执行
         */
        @Before("repeat()")
        public void repeat(JoinPoint point) {
            // 获取token
            String token = HttpContextUtils.getHttpServletRequest().getHeader("Authorization");
            if(StringUtils.isBlank(token)){
                return;
            }
    
            // 拼接
            StringBuilder label = new StringBuilder(PREFIX + token + HttpContextUtils.getHttpServletRequest().getRequestURI());
    
            // 判断key是否存在
            if(redisTemplate.hasKey(label.toString())){
                operate(label.toString());
            }else {
                set(label.toString());
            }
        }
    
        private void operate(String label) {
            // 上次提交时间
            Long lastTime = Long.valueOf(redisTemplate.opsForValue().get(label).toString());
            if(Objects.isNull(lastTime)){
                return;
            }
            if(System.currentTimeMillis() - lastTime < REPEAT_TIME){
                throw new BusinessException("点击的太快了啦,请慢一点!");
            }else {
                // 限制间隔点击时间已过,重新设置时间
                set(label);
            }
        }
    
        // 设置key
        public void set(String label){
            redisTemplate.opsForValue().set(label, System.currentTimeMillis(),3, TimeUnit.SECONDS);
        }
    
    }
  • 相关阅读:
    I2S波形解析
    F407整点原子I2C波形解码
    WAVE格式文件说明
    ADC结构体初始化成员
    这次,我是真的想吐槽MDK
    I2S源程序(正点原子F407探索者)
    强制类型转换
    嵌套结构体的初始化
    lua 元方法 __index
    lua pairs 与 ipairs
  • 原文地址:https://www.cnblogs.com/hjieone/p/15785107.html
Copyright © 2020-2023  润新知