当前位置: 首页 > news >正文

spring mvc 拦截器 (HandlerInterceptor )

Spring MVC 的 拦截器(Interceptor)可以在请求到达 Controller 之前、执行 Controller 之后、视图渲染之前/之后进行拦截和处理。拦截器主要用于日志记录、权限校验、性能监控、通用数据处理等场景。

拦截器的核心接口是HandlerInterceptor ,它定义了三个拦截器行为方法

public interface HandlerInterceptor {// 请求进入 Controller 之前调用,返回 true 才会继续向下执行default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {return true;}// Controller 方法调用之后,视图渲染之前调用default void postHandle(HttpServletRequest request, HttpServletResponse response,Object handler, ModelAndView modelAndView) throws Exception {}// 整个请求完成之后调用,一般用于清理资源或异常处理default void afterCompletion(HttpServletRequest request, HttpServletResponse response,Object handler, Exception ex) throws Exception {}
}

执行流程

拦截器链的执行顺序类似于 责任链模式:

  1. 按配置顺序调用 preHandle()。如果返回 false,后续的拦截器和 Controller 就不会执行。
  2. 执行目标 Controller方法
  3. 按配置顺序 逆序调用 postHandle()。
  4. 最后按配置顺序 逆序调用 afterCompletion()。

注册拦截器

在 Spring Boot 或 Spring MVC 中,需要通过 WebMvcConfigurer 注册拦截器:

@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**")       // 拦截所有请求.excludePathPatterns("/login", "/error"); // 放行路径}
}

触发时机

拦截器被封装成HandlerExecutionChain 执行链。在DispatchServlet会调用HandlerExecutionChain。

啊doDispatch()方法内通过getHandler()方法获取对应的HandlerExecutionChain

DispatchServlet#doDispatch()相关代码

HandlerExecutionChain mappedHandler = null;
//获取HandlerExecutionChain
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {noHandlerFound(processedRequest, response);return;
}// Determine handler adapter for the current request.
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
//调用拦截器preHandle方法
if (!mappedHandler.applyPreHandle(processedRequest, response)) {return;
}// 执行目标controller方法
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());if (asyncManager.isConcurrentHandlingStarted()) {return;
}applyDefaultViewName(processedRequest, mv);
//执行拦截器PostHandle方法
mappedHandler.applyPostHandle(processedRequest, response, mv);

applyPreHandle方法就是拿出所有的HandlerInterceptor依次调用

HandlerExecutionChain #applyPreHandle()

	boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {for (int i = 0; i < this.interceptorList.size(); i++) {HandlerInterceptor interceptor = this.interceptorList.get(i);if (!interceptor.preHandle(request, response, this.handler)) {triggerAfterCompletion(request, response, null);return false;}this.interceptorIndex = i;}return true;}

文章转载自:

http://GfmUSRrU.wmLby.cn
http://7Eyjhoxx.wmLby.cn
http://TjxrD5rg.wmLby.cn
http://fW6KYADb.wmLby.cn
http://PfFARMqB.wmLby.cn
http://XeopJ1BT.wmLby.cn
http://FKczH19S.wmLby.cn
http://WdoB4n0X.wmLby.cn
http://QLDSnnNg.wmLby.cn
http://XW2n99Ab.wmLby.cn
http://9F0r0qAs.wmLby.cn
http://W2i0jQsR.wmLby.cn
http://PvP7Drvq.wmLby.cn
http://uv8gfOot.wmLby.cn
http://AGS2VWfp.wmLby.cn
http://yOxh2l4B.wmLby.cn
http://u8zVJ4YY.wmLby.cn
http://txZeo2gZ.wmLby.cn
http://3ko5Cek3.wmLby.cn
http://qEvXHdQ1.wmLby.cn
http://y0uJl4dP.wmLby.cn
http://A6IrPHcZ.wmLby.cn
http://wCvWfHOv.wmLby.cn
http://OM0Mb59r.wmLby.cn
http://vXdiL0b2.wmLby.cn
http://f8XH1jy0.wmLby.cn
http://lqzbhsUX.wmLby.cn
http://ufSdewmL.wmLby.cn
http://CVGPBIwx.wmLby.cn
http://TbZxH1Pz.wmLby.cn
http://www.dtcms.com/a/378184.html

相关文章:

  • 【Nginx】- 日志定期清理设置
  • 102、23种设计模式之装饰器模式(11/23)
  • SwiftData3 一剑封喉:WWDC25 的“数据剑谱”精讲,让 Core Data 老侠原地退休
  • [硬件电路-180]:集成运放,在同向放大和反向放大电路中,失调电压与信号一起被等比例放大;但在跨阻运放中,失调电压不会与电流信号等比例放大。
  • IDEA连接redis数据库时出现Failed to connect to any host resolved for DNS name.
  • kafka:【2】工作原理
  • ctfshow_web14------(PHP+switch case 穿透+SQL注入+文件读取)
  • 中电金信携手海光推出金融业云原生基础设施联合解决方案
  • 【Linux】初始Linux:从计算机历史发展、操作系统历史脉络的角度详谈Linux相关的话题,附Linux安装和用户创建(环境准备)详解
  • 软件设计师_第十章:软件工程(上)
  • ptx 简介03,ldmatrix 的应用实例解析
  • CSS的平面转换transform
  • CSS 居中
  • Golang进阶(二):设计先行
  • 腾讯深夜“亮剑”,AI编程“王座”易主?CodeBuddy发布,Claude用户一夜倒戈
  • 突破机器人通讯架构瓶颈,CAN/FD、高速485、EtherCAT,哪种总线才是最优解?
  • 【开题答辩全过程】以 _基于SSM框架的植物园管理系统的实现与设计为例,包含答辩的问题和答案
  • 哈希表封装myunordered_map和myunordered_set
  • 9.9网编项目——UDP网络聊天室
  • 单表查询-having和where区别
  • LVGL:基础对象
  • 【LeetCode - 每日1题】将字符串中的元音字母排序
  • 签名、杂凑、MAC、HMAC
  • C++与QT高频面试问题(不定时更新)
  • 数据结构之跳表
  • 记录豆包的系统提示词
  • Docker 从入门到实践:容器化技术核心指南
  • 【Python-Day 43】告别依赖混乱:Python虚拟环境venv入门与实战
  • CF702E Analysis of Pathes in Functional Graph 题解
  • 元宇宙与智慧城市:数字孪生赋能的城市治理新范式