【WEB系列】SpringBoot之拦截器Interceptor使用姿势介绍
source link: https://spring.hhui.top/spring-blog/2021/08/04/210804-SpringBoot%E7%B3%BB%E5%88%97Web%E7%AF%87%E4%B9%8B%E6%8B%A6%E6%88%AA%E5%99%A8Interceptor%E4%BD%BF%E7%94%A8%E5%A7%BF%E5%8A%BF%E4%BB%8B%E7%BB%8D/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
【WEB系列】SpringBoot之拦截器Interceptor使用姿势介绍
在SpringMVC中,拦截器与Filter两者的应用场景好像差不多,最大的区别可能是前者属于Spring的特产,而后者则是Servlert三剑客中的一个,它们本质的区别在于两者发生的时机不一致
- Filter: 在执行Servlet#service方法之前,会执行过滤器;执行完毕之后也会经过过滤器
- Interceptor: 对会话进行拦截,可以在调用Handler方法之前,视图渲染之前,方法返回之前三个时机触发回调
基于上面的触发时间的不同,两者可以做的事情也不尽相同
- Filter: 操作Request/Response
- Interceptor: 操作Request/Response/handler/modelAndView/exception
接下来本文将来看一下,在SpringMVC中拦截器的使用姿势
I. 项目搭建
1. 项目依赖
本项目借助SpringBoot 2.2.1.RELEASE
+ maven 3.5.3
+ IDEA
进行开发
开一个web服务用于测试
<dependencies>
<!-- 邮件发送的核心依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
II. 拦截器
1. 自定义拦截器
要实现一个自定义拦截器,一般来讲,实现接口HandlerInterceptor
即可
@Slf4j
public class SecurityInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 一个简单的安全校验,要求请求头中必须包含 req-name : yihuihui
String header = request.getHeader("req-name");
if ("yihuihui".equals(header)) {
return true;
}
log.info("请求头错误: {}", header);
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.info("执行完毕!");
response.setHeader("res", "postHandler");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
log.info("回收");
}
}
这个接口定义了三个方法,分别在不同的时机触发回调
1.1 preHandle
在handler方法执行之前(简单理解为Controller提供的服务调用之前)会被触发,如果返回ture,表示拦截通过,可以执行;若果返回false,表示不允许往后走
因此在这里,通常可以用来做安全校验,用户身份处理等操作
特别需要注意的是,无论是拦截器/还是Filter,在使用 Request 中的请求流的时候,要警惕,通常请求参数流的读取是一次性的,如果在这里实现了一个请求参数日志输出,把请求流的数据读出来了,但是又没有写回去,就会导致请求参数丢失了
1.2 postHandler
这个是在handler方法执行之后,视图渲染之前被回调,简单来说,我们在这个时候,是可以操作ModelAndView,往里面添加一下信息,并能被视图解析渲染的
当然鉴于现在前后端分离的趋势,这个实际上用得也不多了
1.3 afterCompletion
顾名思义,该方法将在整个请求结束之后,也就是在 DispatcherServlet 渲染了对应的视图之后执行。此方法主要用来进行资源清理
2. 注册与测试
接下来让我们自定义的拦截器生效
实现WebMvcConfigurer
接口,重写addInterceptors
方法,实现拦截器注册
@RestController
@SpringBootApplication
public class Application implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new SecurityInterceptor()).addPathPatterns("/**");
}
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
@GetMapping(path = "show")
public String show() {
return UUID.randomUUID().toString();
}
}
本文补齐了之前遗漏的SpringMVC拦截器的知识点,从使用来看,比较简单,需要注意的知识点,无非就是拦截器的三个时机
- preHander: controller方法执行前触发,返回ture/false, ture表示通过
- postHandler: controller执行后,视图渲染前
- afterCompletion: 执行完毕之后触发
其次,相较于filter而言, 拦截器除了操作requset/response之外,还可以操作handler/modelAndView/exception
III. 不能错过的源码和相关知识点
1. 一灰灰Blog
尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激
下面一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛
一灰灰blog
Recommend
-
92
前年的这个时候我们项目将网络框架替换为 okhttp+retrofit ,然后我对 retrofit 源码进行了学习和分享,写了几篇相关的文章同时更新了项目的网络框架。
-
8
Vert.x技巧:使用EventBus-Interceptor拦截消息胡键 Posted at — Feb 7, 2017 阅读 36Vert.x用久了肯定有这样的想法:拦截 EventBus 上发送的所有消息。这个需求用 Vertx EventBus Interceptor...
-
4
-
5
前面一篇博文介绍了一个@Value的一些知识点,其中提了一个点,@Value对应的配置,除了是配置文件中之外,可以从其他的数据源中获取么,如从redis,db,http中获取配置? 了解过SpringCloud Config的可以给出确切的答案,可以...
-
6
在Mybatis中,插件机制提供了非常强大的扩展能力,在sql最终执行之前,提供了四个拦截点,支持不同场景的功能扩展 Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed) ParameterHandler (get...
-
7
邮件发送,在实际的项目开发中,可能用的不是特别多,如果没有特定的需求,相信也没有多少小伙伴会特意的去关注,那么如果现在我们希望针对项目做一个异常的报警系统,当出现异常的时候,可以向指定的小伙伴发送邮件提醒,那么让我们来实现这个功能,可以怎么办...
-
8
之前介绍过一篇拦截器的基本使用姿势:
-
4
一、拦截器概念 讲解拦截器的概念之前,我们先看一张图: ...
-
4
在我们日常的开发中,我们经常会用到Filter和Interceptor。有时同一个功能。Filter可以做,Interceptor也可以做。有时就需要考虑使用哪一个比较好。这篇文章主要介绍一下,二者的区别和联系。希望给大家进行选择的时候,提供一些帮助 ...
-
8
【译】.NET 8 拦截器(interceptor) ...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK