【防止用户连点】

作用

防止用户连点。

依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

redis 配置

spring:
  redis:
    # Redis服务器地址
    host: 192.168.18.128
    # Redis服务器端口号
    port: 6379
    # 使用的数据库索引,默认是0
    database: 0
    # 连接超时时间
    timeout: 1800000
    # 设置密码
    #password: "123456"
    lettuce:
      pool:
        # 最大阻塞等待时间,负数表示没有限制
        max-wait: -1
        # 连接池中的最大空闲连接
        max-idle: 5
        # 连接池中的最小空闲连接
        min-idle: 0
        # 连接池中最大连接数,负数表示没有限制
        max-active: 20

拦截器

package com.toplion.interceptor;

import com.toplion.annotation.AccessLimit;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        //获取注解
        AccessLimit methodAnnotation = handlerMethod.getMethodAnnotation(AccessLimit.class);
        if (Objects.isNull(methodAnnotation)) {
            return true;
        }
        //获取注解值
        int maxCount = methodAnnotation.maxCount();
        int seconds = methodAnnotation.seconds();
        //redis设置参数
        String ip = request.getRemoteAddr();
        String key = request.getServletPath() + ":" + ip;
        String count = redisTemplate.opsForValue().get(key);
        if (StringUtils.isBlank(count)) {
            redisTemplate.opsForValue().set(key, "1", seconds, TimeUnit.SECONDS);
            return true;
        }
        //获取redis中的值并对比
        int countNum = Integer.parseInt(count);
        if (countNum < maxCount) {
            redisTemplate.opsForValue().increment(key);
        } else {
            //response 返回 json 请求过于频繁请稍后再试
            response.setStatus(401);
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            response.getWriter().write("操作频繁,请稍后重试");
            return false;
        }
        return true;
    }
}

添加进拦截器

package com.toplion.config;

import com.toplion.interceptor.LoginInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

    @Autowired
    private LoginInterceptor loginInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor);
    }
}

测试

正常情况

redis中的值

超过次数

次数为三次每分钟

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值