限制接口一定时间内调用次数,超过次数就延时后调用

@Documented
@Target(ElementType.METHOD) // 说明该注解只能放在方法上面
@Retention(RetentionPolicy.RUNTIME)
public @interface LimitRequest {
    long time() default 60; // 限制时间 单位:秒
    int count() default 1; // 允许请求的次数
}
@Aspect
@Component
public class LimitRequestAspect {

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private CacheComponent cacheComponent;

    private static ConcurrentHashMap<String,Map<String, Integer>> book = new ConcurrentHashMap<>();

    private static final String LIMIT_REQUEST = "limit_request";
    private static final String LIMIT_REQUEST_EXCEPTION = "limit_request_exception";

    // 定义切点
    // 让所有有@LimitRequest注解的方法都执行切面方法
    @Pointcut("@annotation(limitRequest)")
    public void excudeService(LimitRequest limitRequest) {
    }

    @Around("excudeService(limitRequest)")
    public Object doAround(ProceedingJoinPoint pjp, LimitRequest limitRequest) throws Throwable {
        ResultData resultData = new ResultData();
        // 获得request对象
        String userId = JwtUtil.getInstance().getIdByParseJWT(request);

        String str = cacheComponent.get(LIMIT_REQUEST_EXCEPTION + userId);
        if(StringUtils.isNotBlank(str)){
            return resultData.fail("请休息一下三分钟后再试");
        }
        //获取缓存中的数据访问次数没有为0
        String count = cacheComponent.get(LIMIT_REQUEST + userId);
        Integer uCount = StringUtils.isBlank(count) ? 0 : Integer.valueOf(count);
        if (uCount >= limitRequest.count()) { // 超过次数,不执行目标方法延时3分钟
            String srt = "requestException";
            cacheComponent.set(LIMIT_REQUEST_EXCEPTION + userId, JSONObject.toJSONString(srt), 180L);
            return resultData.fail("请休息一下三分钟后再试");
        }else if(uCount == 0){
            // 第一次请求时,设置有效时间
            int setCount = uCount + 1;
            cacheComponent.set(LIMIT_REQUEST + userId, JSONObject.toJSONString(setCount), limitRequest.time());
        }else{
            int setCount = uCount + 1;
            // 未超过次数, 记录加一
            cacheComponent.setValue(LIMIT_REQUEST + userId, JSONObject.toJSONString(setCount));
        }
        // result的值就是被拦截方法的返回值
        Object result = pjp.proceed();
        return result;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值