芜湖营销型网站建设,网站添加在线支付功能,网站需要优化的小型公司,网站做推广团队说明#xff1a;
一些版本比较老的spring框架的#xff0c;是通过继承HandlerInterceptorAdapter并重写preHandle()方法#xff0c;和继承WebMvcConfigurerAdapter并重写 addInterceptors()方法来实现拦截器的#xff0c;但是这两个类很久前就已经过时了#xff0c;不推荐…说明
一些版本比较老的spring框架的是通过继承HandlerInterceptorAdapter并重写preHandle()方法和继承WebMvcConfigurerAdapter并重写 addInterceptors()方法来实现拦截器的但是这两个类很久前就已经过时了不推荐使用推荐使用下面两个接口。
以接口接口限流进行具体的操作自定义拦截器主要步骤就是两个
1、实现HandlerInterceptor并实现rpreHandle前置处理方法
2、实现WebMvcConfigurer并实现addInterceptors增加拦截器方法把自定义的拦截器增加到spring容器中
HandlerInterceptor拦截器处理器接口有三个接口 ● preHandle在业务处理器处理请求之前被调用。预处理可以进行编码、安全控制、权限校验等处理 ● postHandle在业务处理器处理请求执行完成后生成视图之前执行。后处理调用了Service并返回ModelAndView但未进行页面渲染有机会修改ModelAndView ● afterCompletion在DispatcherServlet完全处理完请求后被调用可用于清理资源等。返回处理已经渲染了页面
实操
1、引入依赖
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-aop/artifactId
/dependency
!--Redis依赖--
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId
/dependency2、自定义接口访问注解
/**
* 接口访问限制枚举
* author ppp
* date 2023/2/14
*/
Target({ElementType.METHOD})
Retention(RetentionPolicy.RUNTIME)
public interface AccessLimit {/*** return 访问最大次数*/int accessMaxTimes() default 60;/*** return 时间*/long timeOut() default 1;/*** return 时间单位*/TimeUnit timeUnit() default TimeUnit.MINUTES;
}3、自定义拦截器配置
同时实现HandlerInterceptorWebMvcConfigurer实现preHandle和addInterceptors方法
/**
* 接口访问限制拦截器配置
* author ppp
* date 2023/2/14
*/
Component
public class AccessLimitInterceptorConfig implements HandlerInterceptor, WebMvcConfigurer {private final static String KEY Redis_accessLimit_key;AutowiredRedisTemplate redisTemplate;AutowiredAccessLimitInterceptorConfig accessLimitInterceptorConfig;Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//判断请求是否属于方法的请求if(handler instanceof HandlerMethod){HandlerMethod hm (HandlerMethod) handler;//获取方法中的注解,看是否有该注解AccessLimit accessLimit hm.getMethodAnnotation(AccessLimit.class);if(accessLimit null){return true;}int accessMaxTimes accessLimit.accessMaxTimes();long timeOut accessLimit.timeOut();TimeUnit timeUnit accessLimit.timeUnit();// 如果redis不存在或已经过期Long expire redisTemplate.opsForValue().getOperations().getExpire(KEY);if (!redisTemplate.hasKey(KEY) || Objects.requireNonNull(expire).intValue() 0) {redisTemplate.opsForValue().set(KEY, 1, timeOut, timeUnit);} else {long increment redisTemplate.opsForValue().increment(KEY).intValue();if (increment accessMaxTimes) {throw new RuntimeException(访问已经超过最大值 accessMaxTimes);}}}return true;}Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(accessLimitInterceptorConfig);}
}4、配置redis
/*** Redis管理配置*/
Configuration
public class RedisConfigurer {/*** 设置 redisTemplate 的序列化设置** param redisConnectionFactory* return*/Beanpublic RedisTemplateObject, Object redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplateObject, Object template new RedisTemplate();template.setConnectionFactory(redisConnectionFactory);GenericToStringSerializer genericToStringSerializer new GenericToStringSerializer(Object.class);template.setValueSerializer(genericToStringSerializer);template.setKeySerializer(new StringRedisSerializer());template.setHashKeySerializer(new StringRedisSerializer(Charset.forName(UTF-8)));template.setHashValueSerializer(new StringRedisSerializer(Charset.forName(UTF-8)));template.afterPropertiesSet();return template;}Beanpublic CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {return new RedisCacheManager(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory),this.getRedisCacheConfigurationWithTtl(24 * 60 * 60), // 默认策略未配置的 key 会使用这个this.getRedisCacheConfigurationMap() // 指定 key 策略);}private MapString, RedisCacheConfiguration getRedisCacheConfigurationMap() {MapString, RedisCacheConfiguration redisCacheConfigurationMap new HashMap();return redisCacheConfigurationMap;}private RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Integer seconds) {RedisCacheConfiguration redisCacheConfiguration RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(seconds));return redisCacheConfiguration;}
}5、使用
/*** 一分钟内最多请求10次* param content*/
AccessLimit(accessMaxTimes 10, timeOut 1, timeUnit TimeUnit.MINUTES)
GetMapping(/sendEvent)
public void sendEvent(RequestParam String content) {testService.send(content);
}