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);
    }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM