日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

使用Redis實現接口防抖

作者:何中應 更新時間: 2023-12-09 編程語言

說明:實際開發中,我們在前端頁面上點擊了一個按鈕,訪問了一個接口,這時因為網絡波動或者其他原因,頁面上沒有反應,用戶可能會在短時間內再次點擊一次或者用戶以為沒有點到,很快的又點了一次。導致短時間內發送了兩個請求到后臺,可能會導致數據重復添加。

為了避免短時間內對一個接口訪問,我們可以通過AOP+自定義注解+Redis的方式,在接口上加一個自定義注解,然后通過AOP的前置通知,在Redis中存入一個有效期的值,當訪問接口時這個值還未過期,則拋出異常,以此來避免短時間內對接口的方法。

實現

第一步:創建一個自定義注解,設置兩個屬性,一個是key,一個是這個key在Redis中的有效時間;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 自定義注解
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LimitAccess {

    /**
     * 限制訪問的key
     * @return
     */
    String key();

    /**
     * 限制訪問時間
     * @return
     */
    int times();
}

第二步:創建對應的Aspect;

import com.hezy.annotation.LimitAccess;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;

/**
 * AOP類(通知類)
 */
@Component
@Aspect
public class LimitAspect {

    @Autowired
    private RedisTemplate redisTemplate;

    @Pointcut("@annotation(com.hezy.annotation.LimitAccess)")
    public void pt(){};

    @Around("pt()")
    public Object aopAround(ProceedingJoinPoint pjp) throws Throwable {
        // 獲取切入點上面的自定義注解
        Signature signature = pjp.getSignature();

        MethodSignature methodSignature = (MethodSignature) signature;

        // 獲取方法上面的注解
        LimitAccess limitAccess = methodSignature.getMethod().getAnnotation(LimitAccess.class);

        // 獲取注解上面的屬性
        int limit = limitAccess.times();
        String key = limitAccess.key();

        // 根據key去找Redis中的值
        Object o = redisTemplate.opsForValue().get(key);

        // 如果不存在,說明是首次訪問,存入Redis,過期時間為limitAccess中的time
        if (o == null) {
            redisTemplate.opsForValue().set(key, "", limit, TimeUnit.SECONDS);
            // 執行切入點的方法
            return pjp.proceed();
        } else {
            // 如果存在,說明不是首次訪問,拋出異常
            throw new RuntimeException("訪問過于頻繁");
        }
    }
}

第三步:在需要限制的接口上,加上這個注解,并設置key和限制訪問時間,如下這個這個接口,設置key為set,實際開發中可以設置一個隨機值,或者按照規則自定義設置,times為限制訪問時間;

    @GetMapping("/limit")
    @LimitAccess(key = "limit", times = 10)
    public String limit() {
        return "success";
    }

演示

啟動項目,訪問該接口;

(首次訪問,沒得問題,同時在Redis中存入值)

在這里插入圖片描述


(短時間內,連續訪問,因為Redis中值未過期)

在這里插入圖片描述

在這里插入圖片描述


(10秒之后再訪問,又可以了,Redis中的值過期了)

在這里插入圖片描述

以上就是使用Redis實現接口防抖,避免短時間內連續訪問接口。實際開發中,可以將異常設置為自定義異常。

原文鏈接:https://blog.csdn.net/qq_42108331/article/details/134691925

  • 上一篇:沒有了
  • 下一篇:沒有了
欄目分類
最近更新