自定义注解(接口防刷)

主要是业务场景是为了防止一个接口被同一个用户频繁访问
以下是主要代码

package com.xmcbs.jjcommon.util;

import com.xmcbs.jjcommon.enums.PreventStrategy;

import java.lang.annotation.*;

/**
 * @author :wangjp
 * @date :2023/7/11 11:42
 */
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Prevent {
    /**
     * 限制的时间值(秒)默认60s
     */
    long value() default 5;

    /**
     * 限制规定时间内访问次数,默认只能访问一次
     */
    long times() default 1;

    /**
     * 提示
     */
    String message() default "";
}

以下是注解实现类
将访问存到redis并设置过期时间,如果存在说明在这个时间段重复访问,则将报错信息返回

package com.xmcbs.jjcommon.util;

import com.xmcbs.jeeplusboot.core.exception.BusinessException;
import com.xmcbs.jeeplusboot.core.exception.PlatformException;
import com.xmcbs.jeeplusboot.core.util.StringUtil;
import com.xmcbs.jeeplusboot.core.util.redis.RedisUtil;
import com.xmcbs.jeeplusboot.modules.base.service.PlatFormService;
import com.xmcbs.jeeplusboot.modules.system.entity.SystemUser;
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.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * @author :wangjp
 * @date :2023/7/11 14:45
 */
@Aspect
@Component
public class PreventAop {
    @Resource
    private RedisTemplate<String, Long> redisTemplate;
    @Autowired
    private PlatFormService platFormService;


    /**
     * 切入点
     */
    @Pointcut("@annotation(com.xmcbs.jjcommon.util.Prevent)")
    public void pointcut() {}


    /**
     * 处理前
     */
    @Before("pointcut()")
    public void joinPoint(JoinPoint joinPoint) throws Exception {
        SystemUser systemUser = platFormService.getCurrentUser();
        // 获取调用者ip
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        HttpServletRequest httpServletRequest = ((ServletRequestAttributes) requestAttributes).getRequest();
//        String userIP = IpUtils.getUserIP(httpServletRequest);
        // 获取调用接口方法名
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = joinPoint.getTarget().getClass().getMethod(
                methodSignature.getName(),
                methodSignature.getParameterTypes()); // 获取该接口方法
        String methodFullName = method.getDeclaringClass().getName() + method.getName(); // 获取到方法名
        Prevent preventAnnotation = method.getAnnotation(Prevent.class); // 获取该接口上的prevent注解(为了使用该注解内的参数)
        String json = RedisUtil.get("Prevent:" + method.getName() + ":" + systemUser.getId());
        if(StringUtil.isEmpty(json)){
            System.out.println(preventAnnotation.times());
            RedisUtil.set("Prevent:" + method.getName() + ":" + systemUser.getId(),systemUser.getId(),preventAnnotation.times());
        }else{
            throw new PlatformException(preventAnnotation.message());
        }


    }

}

使用:在调用接口上面加注解就行了
不加参数就是默认类里面的参数
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值