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

HandlerInterceptor介绍-笔记

1. HandlerInterceptor简介

org.springframework.web.servlet.HandlerInterceptor 是 Spring MVC 中用于拦截 HTTP 请求的核心接口。

public interface HandlerInterceptor {default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {return true;}default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {}default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {}
}

HandlerInterceptor 的核心方法介绍

  1. preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

    • 作用:在请求处理之前执行(即在控制器方法执行前)。
    • 返回值:返回 true 表示继续后续处理;返回 false 表示中断请求(直接返回响应)。
    • 典型用途:权限校验、请求日志记录。
  2. postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)

    • 作用:在请求处理完成后、视图渲染之前执行。
    • 参数说明modelAndView 是控制器方法返回的结果。
    • 典型用途:修改模型数据、记录响应日志。
  3. afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)

    • 作用:在整个请求完成时执行(即视图渲染结束后)。
    • 典型用途:资源清理、异常处理、性能统计。

它允许开发者在请求处理的不同阶段插入自定义逻辑,例如权限验证、日志记录、性能监控等。通过实现该接口的三个关键方法,可以灵活控制请求的处理流程。

2. 使用示例

2.1 日志拦截器demo

下面以一个 日志拦截器 为例,演示如何使用HandlerInterceptor。

step1.实现 HandlerInterceptor 接口

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.UUID;public class LoggingHandlerInterceptor implements HandlerInterceptor {// 请求处理前执行@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {String requestId = UUID.randomUUID().toString();request.setAttribute("requestId", requestId);System.out.println("=== PreHandle ===");System.out.println("Request ID: " + requestId);System.out.println("Request URL: " + request.getRequestURL());return true; // 继续后续处理}// 请求处理后、视图渲染前执行@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) {System.out.println("=== PostHandle ===");if (modelAndView != null) {System.out.println("View Name: " + modelAndView.getViewName());return;}System.out.println("No view");}// 请求完成时执行@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,Exception ex) {System.out.println("=== AfterCompletion ===");if (ex != null) {System.out.println("Exception occurred: " + ex.getMessage());}System.out.println("Response Status: " + response.getStatus());System.out.println("Request ID: " + request.getAttribute("requestId"));}
}

step2.注册拦截器到 Spring MVC 配置

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class HandlerInterceptorWebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoggingHandlerInterceptor()).addPathPatterns("/**") // 拦截所有路径.excludePathPatterns("/public/**"); // 排除特定路径;}
}

step3.创建测试controller

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class HandlerInterceptorController {@GetMapping("HandlerInterceptorController/test")public String test() {return "test";}
}

step4. 测试

启动应用,浏览器输入  http://127.0.0.1:8080/HandlerInterceptorController/test ,日志输出如下:

2.2 其他使用场景demo

2.2.1 权限验证

在 preHandle 中检查用户是否登录,未登录则重定向到登录页面:

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {if (userNotAuthenticated(request)) {response.sendRedirect("/login");return false; // 中断请求}return true;
}

2.2.2 性能监控

在 preHandle 记录开始时间,在 afterCompletion 计算耗时:

private Long startTime;@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {startTime = System.currentTimeMillis();return true;
}@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {long duration = System.currentTimeMillis() - startTime;System.out.println("Request took " + duration + " ms");
}

2.3 注意事项

  1. 拦截器顺序:多个拦截器时,注册顺序决定执行顺序preHandle 按注册顺序执行,afterCompletion 按逆序执行)。
  2. 异常处理afterCompletion 中可以通过 Exception ex 参数捕获控制器抛出的异常。
  3. 线程安全:拦截器默认是单例的,避免在拦截器中使用成员变量存储请求相关数据(可通过 request.setAttribute 传递)。

相关文章:

  • NC65开发环境(eclipse启动)在企业报表中的报表数据中心里计算某张报表时,一直计算不出数据的解决办法。
  • C++类和对象练习:Date类实现日期的差,比较日期的大小,日期的前置后置++,--,输入输出Date类,对默认函数的练习。
  • uniapp使用全局组件,
  • Django + Celery 打造企业级大模型异步任务管理平台 —— 从需求到完整实践(含全模板源码)
  • VCS X-PROP建模以及在方针中的应用
  • 【MySQL】变更缓冲区:作用、主要配置以及如何查看
  • 记录: Windows下远程Liunx 系统xrdp 用到的一些小问题(免费踩坑 记录)
  • 海量数据Top k 与查重问题
  • 【FFmpeg】介绍+安装+VisualStudio配置FFMpeg库
  • 谷歌web第三方登录
  • .NET NativeAOT 指南
  • 鸿蒙OSUniApp打造多功能图表展示组件 #三方框架 #Uniapp
  • Java 重试机制详解
  • 鸿蒙OSUniApp 实现的二维码扫描与生成组件#三方框架 #Uniapp
  • 1688 平台 API 接口深度解析:高效获取商品详情数据的开发实践
  • 国产免费工作流引擎star 6.5k,Warm-Flow升级1.7.2(新增案例和修复缺陷)
  • LLaMA-Factory 微调 Qwen2-7B-Instruct
  • 【vim】--- vim 插件说明 超详细持续更新中
  • 车载网关--- 职责边界划分与功能解耦设计
  • JVM 精华
  • 以军向也门3个港口的居民发布撤离令
  • 乌总统:若与普京会谈,全面停火和交换战俘是主要议题
  • 中央结算公司:减免境外央行类机构账户开户费用
  • 比特币挖矿公司GRYP股价涨超171%:将与特朗普儿子创设的公司合并
  • 盖茨说对中国技术封锁起到反作用
  • 寒武纪陈天石:公司的产品力获得了行业客户广泛认可,芯片市场有望迎来新增量需求