springboot拦截器拦截提示_springboot 自定义拦截器 防止恶意请求

该例子需要用到 redis

在applocation.properties中加入redis的配置信息

server.port=8030

# Redis数据库索引(默认为0)

spring.redis.database=0

# Redis服务器地址

spring.redis.host=localhost

# Redis服务器连接端口

spring.redis.port=6379

# Redis服务器连接密码(默认为空)

spring.redis.password=

#连接池最大连接数(使用负值表示没有限制)

spring.redis.jedis.pool.max-idle=8

# 连接池最大阻塞等待时间(使用负值表示没有限制)

spring.redis.jedis.pool.max-wait=

# 连接池中的最大空闲连接

spring.redis.jedis..pool.max-idle=8

# 连接池中的最小空闲连接

spring.redis.jedis.pool.min-idle=0

# 连接超时时间(毫秒)

spring.redis.timeout=300

RedisConfig.java

packagecn.rc.config;importorg.springframework.cache.annotation.CachingConfigurerSupport;importorg.springframework.cache.annotation.EnableCaching;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.data.redis.connection.RedisConnectionFactory;importorg.springframework.data.redis.core.RedisTemplate;importorg.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;importorg.springframework.data.redis.serializer.StringRedisSerializer;importcom.fasterxml.jackson.annotation.JsonAutoDetect;importcom.fasterxml.jackson.annotation.PropertyAccessor;importcom.fasterxml.jackson.databind.ObjectMapper;

@Configuration

@EnableCaching//开启注解

public class RedisConfig extendsCachingConfigurerSupport {

@Beanpublic RedisTemplateredisTemplate(RedisConnectionFactory factory) {

RedisTemplate template = new RedisTemplate<>();//配置连接工厂

template.setConnectionFactory(factory);//使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)

Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class);

ObjectMapper om= newObjectMapper();//指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public

om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);//指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常

om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

jacksonSeial.setObjectMapper(om);//值采用json序列化

template.setValueSerializer(jacksonSeial);//使用StringRedisSerializer来序列化和反序列化redis的key值

template.setKeySerializer(newStringRedisSerializer());//设置hash key 和value序列化模式

template.setHashKeySerializer(newStringRedisSerializer());

template.setHashValueSerializer(jacksonSeial);

template.afterPropertiesSet();returntemplate;

}

}

需要先启动redis功能

一、声明一个自定义的注解类

AccessLimit.java

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.METHOD)public @interfaceAccessLimit {intseconds();intmaxCount();boolean needLogin() default true;

}

二、声明一个自定义的拦截器:

AccessLimtInterceptor.java

@Componentpublic class AccessLimtInterceptor implementsHandlerInterceptor {

@AutowiredprivateRedisTemplate redisTemplate;

@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throwsException {if (handler instanceofHandlerMethod) {

HandlerMethod hm=(HandlerMethod) handler;

AccessLimit accessLimit= hm.getMethodAnnotation(AccessLimit.class);if (null ==accessLimit) {return true;

}int seconds =accessLimit.seconds();int maxCount =accessLimit.maxCount();boolean needLogin =accessLimit.needLogin();if(needLogin) {//判断是否登录

}

String ip=request.getRemoteAddr();

String key= request.getServletPath() + ":" +ip ;

Integer count=(Integer) redisTemplate.opsForValue().get(key);if (null == count || -1 ==count) {

redisTemplate.opsForValue().set(key,1,seconds, TimeUnit.SECONDS);return true;

}if (count

count= count+1;

redisTemplate.opsForValue().set(key, count,0);return true;

}if (count >=maxCount) {//response 返回 json 请求过于频繁请稍后再试

response.setCharacterEncoding("UTF-8");

response.setContentType("application/json; charset=utf-8");

JsonResponse result= new JsonResponse<>();

result.setCode(9999);

result.setMessage("操作过于频繁");

Object obj=JSONObject.toJSON(result);

response.getWriter().write(JSONObject.toJSONString(obj));return false;

}

}return true;

}

}

将 拦截器 注册到容器:WebMvcConfig.java

/*** MVC 设置

**/@Configurationpublic class WebMvcConfig extendsWebMvcConfigurerAdapter {

@AutowiredprivateAccessLimtInterceptor accessLimtInterceptor;

@BeanpublicAccessTokenVerifyInterceptor tokenVerifyInterceptor() {return newAccessTokenVerifyInterceptor();

}

@Overridepublic voidaddInterceptors(InterceptorRegistry registry) {

registry.addInterceptor(accessLimtInterceptor);

registry.addInterceptor(tokenVerifyInterceptor()).addPathPatterns("/**");super.addInterceptors(registry);

}

}

进行测试接口:

使用 @AccessLimit(seconds = 15, maxCount = 3)  注解 修饰接口 , 15秒 只允许访问3次

@RestController

@RequestMapping("test")public classTestAccessLimitController {

@GetMapping("accessLimit")

@AccessLimit(seconds= 15, maxCount = 3) //15秒内 允许请求3次

publicString testAccessLimit() {return "success";

}

}

返回: success

快速刷新多次后出现:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值