持续原创输出,点击上方蓝字关注我吧
前言
–
上篇文章讲了Spring Boot的WEB开发基础内容,相信读者朋友们已经有了初步的了解,知道如何写一个接口。
今天这篇文章来介绍一下拦截器在Spring Boot中如何自定义以及配置。
Spring Boot 版本
本文基于的Spring Boot的版本是2.3.4.RELEASE
。
什么是拦截器?
Spring MVC中的拦截器(Interceptor
)类似于Servlet中的过滤器(Filter
),它主要用于拦截用户请求并作相应的处理。例如通过拦截器可以进行权限验证、记录请求信息的日志、判断用户是否登录等。
如何自定义一个拦截器?
自定义一个拦截器非常简单,只需要实现HandlerInterceptor
这个接口即可,该接口有三个可以实现的方法,如下:
preHandle()
方法:该方法会在控制器方法前执行,其返回值表示是否知道如何写一个接口。中断后续操作。当其返回值为true
时,表示继续向下执行;当其返回值为false
时,会中断后续的所有操作(包括调用下一个拦截器和控制器类中的方法执行等)。postHandle()
方法:该方法会在控制器方法调用之后,且解析视图之前执行。可以通过此方法对请求域中的模型和视图做出进一步的修改。afterCompletion()
方法:该方法会在整个请求完成,即视图渲染结束之后执行。可以通过此方法实现一些资源清理、记录日志信息等工作。
如何使其在Spring Boot中生效?
其实想要在Spring Boot生效其实很简单,只需要定义一个配置类,实现WebMvcConfigurer
这个接口,并且实现其中的addInterceptors()
方法即可,代码演示如下:
1 | 复制代码@Configuration |
举个栗子
开发中可能会经常遇到短时间内由于用户的重复点击导致几秒之内重复的请求,可能就是在这几秒之内由于各种问题,比如网络
,事务的隔离性
等等问题导致了数据的重复等问题,因此在日常开发中必须规避这类的重复请求操作,今天就用拦截器简单的处理一下这个问题。
思路
在接口执行之前先对指定接口(比如标注某个注解
的接口)进行判断,如果在指定的时间内(比如5秒
)已经请求过一次了,则返回重复提交的信息给调用者。
根据什么判断这个接口已经请求了?
根据项目的架构可能判断的条件也是不同的,比如IP地址
,用户唯一标识
、请求参数
、请求URI
等等其中的某一个或者多个的组合。
这个具体的信息存放在哪里?
由于是短时间
内甚至是瞬间并且要保证定时失效
,肯定不能存在事务性数据库中了,因此常用的几种数据库中只有Redis
比较合适了。
如何实现?
第一步,先自定义一个注解,可以标注在类或者方法上,如下:
1 | 复制代码@Target({ElementType.METHOD, ElementType.TYPE}) |
第二步,创建一个拦截器,注入到IOC容器中,实现的思路很简单,判断controller的类或者方法上是否标注了@RepeatSubmit
这个注解,如果标注了,则拦截判断,否则跳过,代码如下:
1 | 复制代码/** |
第三步,在Spring Boot中配置这个拦截器,代码如下:
1 | 复制代码@Configuration |
OK,拦截器已经配置完成,只需要在需要拦截的接口上标注@RepeatSubmit
这个注解即可,如下:
1 | 复制代码@RestController |
此时,请求这个URI:http://localhost:8080/springboot-demo/user/login
在5秒之内只能请求一次。
注意:标注在方法上的超时时间会覆盖掉类上的时间,因为如下一段代码:
1 | 复制代码Boolean ifAbsent = stringRedisTemplate.opsForValue().setIfAbsent(uri, "", Objects.nonNull(repeatSubmitByMethod)?repeatSubmitByMethod.seconds():repeatSubmitByCls.seconds(), TimeUnit.SECONDS); |
这段代码的失效时间先取值repeatSubmitByMethod
中配置的,如果为null,则取值repeatSubmitByCls
配置的。
总结
至此,拦截器的内容就介绍完了,其实配置起来很简单,没什么重要的内容。
本文转载自: 掘金