java实现限制接口访问次数

1.添加pox依赖

<!-- AOP -->
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.9.4</version>
		</dependency>

<!--Map依赖 -->
		<dependency>
			<groupId>net.jodah</groupId>
			<artifactId>expiringmap</artifactId>
			<version>0.5.10</version>
		</dependency>

2.创建自定义注解;

@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LimitRequest {
    //毫秒,分钟,小时 之间的转换用算数
    long time() default 60000*60*24; // 限制时间 单位:毫秒
    int count() default Integer.MAX_VALUE; // 允许请求的次数

}

3.创建aop切面类:

@Aspect
@Component
public class LimitRequestAspect {
    private static ConcurrentHashMap<String, ExpiringMap<String, Integer>> book = new ConcurrentHashMap<>();
    // 定义切点
    // 让所有有@LimitRequest注解的方法都执行切面方法
    @Pointcut("@annotation(limitRequest)")
    public void excudeService(LimitRequest limitRequest) {
    }

    @Around("excudeService(limitRequest)")
    public Object doAround(ProceedingJoinPoint pjp, LimitRequest limitRequest) throws Throwable {
        // 获得request对象
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = sra.getRequest();

        // 获取Map对象, 如果没有则返回默认值
        // 第一个参数是key, 第二个参数是默认值
        ExpiringMap<String, Integer> map = book.getOrDefault(request.getRequestURI(), ExpiringMap.builder().variableExpiration().build());
        Integer uCount = map.getOrDefault(request.getRemoteAddr(), 0);


        if (uCount >= limitRequest.count()) { // 超过次数,不执行目标方法
         //这里的返回对象类型根据controller方法的返回方式一致
           return AjaxResult.error(500,"接口访问次数超过限制,请12小时候重试");
        } else if (uCount == 0){ // 第一次请求时,设置开始有效时间
            map.put(request.getRemoteAddr(), uCount + 1, ExpirationPolicy.CREATED, limitRequest.time(), TimeUnit.MILLISECONDS);
        } else { // 未超过次数, 记录数据加一
            map.put(request.getRemoteAddr(), uCount + 1);
        }
        book.put(request.getRequestURI(), map);

        // result的值就是被拦截方法的返回值
        Object result = pjp.proceed();

        return result;
    }

}

3.在需要限制访问的接口方法上添加我们自定义的注解:

 
    @ApiOperation(value = "查询学生全部信息")
    //其中count指的是规定时间内的访问次数,表示该接口在我们设置的默认时间内只能访问3次,默认时间在自定义注解里面设置的
    @LimitRequest(count=3)
    @GetMapping("/findAll")
    public R findAll(Student student){
        List<Student> students = studentService.findAll(student);
        return R.ok().data("students",students);
    }

  • 10
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
要统计Java接口的调用次数,可以使用AOP(面向切面编程)技术,在接口调用时拦截请求,并记录接口调用次数。 具体实现步骤如下: 1. 定义一个注解,用于标记需要统计调用次数接口方法。 例如: ```java @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Count { } ``` 2. 创建一个切面类,使用@Aspect注解标记,并在类中定义一个切点,用于匹配被@Count注解标记的方法。 例如: ```java @Aspect @Component public class CountAspect { private Map<String, Integer> countMap = new ConcurrentHashMap<>(); @Pointcut("@annotation(com.example.demo.annotation.Count)") public void countPointcut() { } @Around("countPointcut()") public Object countAround(ProceedingJoinPoint joinPoint) throws Throwable { String methodName = joinPoint.getSignature().getName(); String className = joinPoint.getSignature().getDeclaringTypeName(); String key = className + "." + methodName; Integer count = countMap.get(key); if (count == null) { count = 1; } else { count++; } countMap.put(key, count); Object result = joinPoint.proceed(); return result; } } ``` 在上述代码中,我们使用了ConcurrentHashMap来存储每个接口方法的调用次数,初始值为1,每次调用自增1。 3. 在需要统计调用次数接口方法上添加@Count注解。 例如: ```java @RestController @RequestMapping("/demo") public class DemoController { @Autowired private DemoService demoService; @Count @GetMapping("/hello") public String hello() { return "hello"; } @GetMapping("/count") public Map<String, Integer> count() { return demoService.getCountMap(); } } ``` 在上述代码中,我们在hello()方法上添加了@Count注解,表示需要统计该方法的调用次数。 4. 创建一个服务类,用于获取调用次数的统计结果。 例如: ```java @Service public class DemoService { @Autowired private CountAspect countAspect; public Map<String, Integer> getCountMap() { return countAspect.getCountMap(); } } ``` 在上述代码中,我们通过@Autowired注解注入了CountAspect切面类,并通过该类的getCountMap()方法获取到统计结果。 最后,启动应用程序,在浏览器中访问/hello接口,多次刷新页面,然后访问/count接口,即可获取到接口方法调用次数的统计结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值