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

详细分析SpringMvc中HandlerInterceptor拦截器的基本知识(附Demo)

目录

  • 前言
  • 1. 基本知识
  • 2. Demo
  • 3. 实战解析

前言

对于Java的基本知识推荐阅读:

  1. java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全)
  2. 【Java项目】实战CRUD的功能整理(持续更新)

1. 基本知识

HandlerInterceptor 是 Spring MVC 提供的一种机制,用来在请求处理的不同阶段进行拦截

它通常用于日志记录、权限校验、性能监控等操作
继承 HandlerInterceptor 允许定义自定义的逻辑,在请求被处理之前、之后以及完成后执行额外的任务

HandlerInterceptor 接口中包含三个主要方法

  • preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
    在请求处理之前调用(即在控制器方法调用之前)
    返回 boolean 类型,如果返回 true,则继续处理请求;如果返回 false,则中断请求

  • postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
    在请求被处理之后、视图被渲染之前调用
    用于对 ModelAndView 做进一步的修改或处理

  • afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
    在整个请求完成后(包括视图渲染完成后)调用
    用于清理资源、记录日志或执行后续的逻辑

HandlerInterceptor 使用场景

  1. 日志记录:拦截请求并记录请求信息,如 URL、参数、处理时间等
  2. 权限校验:在进入控制器方法之前,检查用户是否有权限访问某个资源
  3. 性能监控:统计每个请求的耗时,以便优化性能
  4. 会话管理:检查用户会话状态,判断用户是否已经登录

基本的 API 介绍

  • HttpServletRequest:表示客户端的请求,可以从中获取请求的 URL、参数、请求体等
  • HttpServletResponse:表示服务器端的响应,可以向客户端写入响应数据
  • Handler:处理器,通常是控制器方法或其代理对象(通常是 HandlerMethod)
  • ModelAndView:封装了数据模型和视图信息,可以在 postHandle 方法中对其进行修改

使用 HandlerInterceptor 的步骤

  1. 创建拦截器类:实现 HandlerInterceptor 接口并重写其方法
  2. 注册拦截器:在 Spring 配置中,将自定义的拦截器注册到拦截器链中
  3. 配置拦截路径:可以选择对哪些 URL 进行拦截,或者排除哪些 URL

2. Demo

在这里插入图片描述

  1. 创建一个自定义拦截器类
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@Component
public class MyInterceptor implements HandlerInterceptor {// 在控制器处理请求之前调用@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("preHandle: 请求URL -> " + request.getRequestURI());// 这里可以进行权限校验、记录日志等操作// 如果返回 false,请求会被终止return true;}// 在控制器处理请求之后调用,但在视图渲染之前调用@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("postHandle: 请求处理完毕");}// 在整个请求完成后调用,通常用于资源清理等操作@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("afterCompletion: 请求完成,清理资源");}
}
  1. 注册拦截器

需要将这个拦截器注册到 Spring MVC 中

通常,在配置类中添加拦截器

import org.springframework.beans.factory.annotation.Autowired;
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 WebConfig implements WebMvcConfigurer {@Autowiredprivate MyInterceptor myInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 添加拦截器,并指定拦截路径registry.addInterceptor(myInterceptor).addPathPatterns("/**") // 拦截所有路径.excludePathPatterns("/login", "/register"); // 排除某些路径}
}
  1. 创建简单的测试控制器

为了测试拦截器的效果,可以创建一个简单的控制器:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class TestController {@GetMapping("/test")public String test() {return "拦截器测试成功!";}@GetMapping("/login")public String login() {return "这是登录页面,不会被拦截!";}
}
  1. 运行程序并测试

启动 Spring Boot 应用后,访问 /test URL

在这里插入图片描述

将会在控制台看到以下输出:

preHandle: 请求URL -> /test
postHandle: 请求处理完毕
afterCompletion: 请求完成,清理资源

在这里插入图片描述

如果访问 /login,因为在 WebConfig 中排除了 /login 路径,拦截器不会生效

在这里插入图片描述

总的来说

HandlerInterceptor 是 Spring MVC 中非常有用的拦截器机制,它可以在请求处理的各个阶段执行自定义逻辑

  • 常用的拦截器功能包括日志记录、权限检查、性能监控等
  • 使用步骤:定义拦截器类、注册拦截器、配置拦截路径

3. 实战解析

@Slf4j // 引入 Lombok 提供的注解,用于简化日志的使用,不需要显式定义 logger 对象。
public class ApiAccessLogInterceptor implements HandlerInterceptor {// 定义一个常量,用于存储处理方法(HandlerMethod)的属性名称,这个属性将在后续的过滤器中使用。public static final String ATTRIBUTE_HANDLER_METHOD = "HANDLER_METHOD";// 定义一个常量,用于存储 StopWatch 对象的属性名称,StopWatch 是用于记录请求耗时的计时器。private static final String ATTRIBUTE_STOP_WATCH = "ApiAccessLogInterceptor.StopWatch";/*** 拦截器的前置处理方法 (preHandle),在请求处理前调用。* * @param request  当前的 HttpServletRequest 对象,包含了请求信息。* @param response 当前的 HttpServletResponse 对象,包含了响应信息。* @param handler  请求处理器,通常是一个 Controller 中的方法,或其对应的代理对象。* @return 如果返回 true,则继续执行后续的拦截器或目标方法;如果返回 false,则中断请求流程。*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {// 记录 HandlerMethod(处理方法),将其存储到 request 属性中,以供后续的过滤器或日志使用。HandlerMethod handlerMethod = handler instanceof HandlerMethod ? (HandlerMethod) handler : null;if (handlerMethod != null) {request.setAttribute(ATTRIBUTE_HANDLER_METHOD, handlerMethod);}// 打印请求日志。如果当前环境不是生产环境(非 prod 环境),则执行日志输出。if (!SpringUtils.isProd()) { // 检查当前是否是生产环境,如果不是则记录日志// 获取请求的查询参数,以键值对的形式存储。Map<String, String> queryString = ServletUtils.getParamMap(request);// 如果请求是 JSON 请求类型,则从请求中提取出请求体。String requestBody = ServletUtils.isJsonRequest(request) ? ServletUtils.getBody(request) : null;// 如果既没有查询参数,也没有请求体,则打印无参数的日志;否则打印包含参数或请求体的日志。if (CollUtil.isEmpty(queryString) && StrUtil.isEmpty(requestBody)) {log.info("[preHandle][开始请求 URL({}) 无参数]", request.getRequestURI());} else {log.info("[preHandle][开始请求 URL({}) 参数({})]", request.getRequestURI(),StrUtil.nullToDefault(requestBody, queryString.toString()));}// 计时操作:为请求创建一个 StopWatch(计时器),并启动它,用于后续计算请求的处理耗时。StopWatch stopWatch = new StopWatch();stopWatch.start();// 将 StopWatch 对象存储到 request 的属性中,以便在 afterCompletion 方法中使用。request.setAttribute(ATTRIBUTE_STOP_WATCH, stopWatch);}return true; // 返回 true,表示允许请求继续往下处理。}/*** 拦截器的后置处理方法 (afterCompletion),在整个请求处理完成(包括视图渲染完成)之后调用。* * @param request  当前的 HttpServletRequest 对象,包含了请求信息。* @param response 当前的 HttpServletResponse 对象,包含了响应信息。* @param handler  请求处理器,通常是一个 Controller 中的方法,或其对应的代理对象。* @param ex       如果请求处理过程中出现异常,这里可以捕获到。*/@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {// 打印响应日志。如果当前环境不是生产环境(非 prod 环境),则执行日志输出。if (!SpringUtils.isProd()) {// 从 request 属性中获取在 preHandle 方法中创建的 StopWatch 对象。StopWatch stopWatch = (StopWatch) request.getAttribute(ATTRIBUTE_STOP_WATCH);// 停止计时器,计算请求处理总耗时。stopWatch.stop();// 打印完成请求的日志,包括请求的 URL 和耗时(单位:毫秒)。log.info("[afterCompletion][完成请求 URL({}) 耗时({} ms)]",request.getRequestURI(), stopWatch.getTotalTimeMillis());}}
}

截图如下:

在这里插入图片描述

相关文章:

详细分析SpringMvc中HandlerInterceptor拦截器的基本知识(附Demo)

目录 前言1. 基本知识2. Demo3. 实战解析 前言 对于Java的基本知识推荐阅读&#xff1a; java框架 零基础从入门到精通的学习路线 附开源项目面经等&#xff08;超全&#xff09;【Java项目】实战CRUD的功能整理&#xff08;持续更新&#xff09; 1. 基本知识 HandlerInter…...

阳光能源嵌入式面试及参考答案(2万字长文)

管道能够承载的最大传输数据量是多少? 在嵌入式系统中,管道能够承载的最大传输数据量取决于多个因素。 首先,管道的容量受到操作系统的限制。不同的操作系统对管道的大小有不同的规定。一般来说,管道的容量通常是有限的,并且在不同的操作系统版本和配置下可能会有所不同。…...

P10483 小猫爬山

1. #include<bits/stdc.h> using namespace std; //一个记录小猫的重量&#xff0c;sum记录当前小猫的重量之和 int n, w, a[3000],sum[3000],ans; bool cmp(int a,int b) {return a > b; } //x表示小猫当前的编号&#xff0c;cnt表示缆车的数量 void dfs(int x,int …...

技术速递|加入 .NET 智能组件生态系统

作者&#xff1a;Daniel Roth - 首席产品经理 排版&#xff1a;Alan Wang .NET 智能组件是一组示例嵌入式 UI 组件&#xff0c;使得在应用中轻松添加 AI 启用的功能变得更加简单&#xff0c;例如从剪贴板数据自动填写表单、智能文本补全以及语义搜索等场景。.NET 智能组件演示了…...

python/requests库的使用/爬虫基础工具/

requests 是一个 Python 库&#xff0c;它允许你发送 HTTP 请求。这个库需要单独安装&#xff0c;因为它不是 Python 标准库的一部分 1.让我们安装requests 在控制台运行 pip install requests 使用 requests 发送请求 1.GET 请求&#xff1a; import requestsresponse …...

【STM32-HAL库】MQ2烟雾传感器使用(STM32F407ZET6)

MQ2可燃气体传感器介绍 MQ2是一种广谱气体传感器&#xff0c;能够检测多种可燃气体和烟雾。它是一种低成本、高灵敏度的传感器&#xff0c;广泛应用于家庭和工业环境中的气体监测。 原理 MQ2传感器的工作原理基于金属氧化物半导体&#xff08;MOX&#xff09;技术。当传感器暴露…...

玩转指针(3)

一、字符指针变量 字符指针变量&#xff08;如char* p&#xff09;的两种赋值方式 ①将字符类型地址赋值给字符指针变量 int main() {char a w;char* p &a;*p m;return 0; }②将常量字符串赋值给字符指针变量 常量字符串的介绍&#xff1a;用" "引起来的就…...

【CSS in Depth 2 精译_040】6.3 CSS 定位技术之:相对定位(下)—— 用纯 CSS 绘制一个三角形

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第一章 层叠、优先级与继承&#xff08;已完结&#xff09;第二章 相对单位&#xff08;已完结&#xff09;第三章 文档流与盒模型&#xff08;已完结&#xff09;第四章 Flexbox 布局&#xff08;已…...

HTML流光爱心

文章目录 序号目录1HTML满屏跳动的爱心&#xff08;可写字&#xff09;2HTML五彩缤纷的爱心3HTML满屏漂浮爱心4HTML情人节快乐5HTML蓝色爱心射线6HTML跳动的爱心&#xff08;简易版&#xff09;7HTML粒子爱心8HTML蓝色动态爱心9HTML跳动的爱心&#xff08;双心版&#xff09;1…...

java技能

日志实际使用 log.error(“111”,e);和 System.out.println(ExceptionUtils.getStackTrace(error)); 日志查询 tail -f root.log 前端页面命名&#xff1a; mounted(){ document.title‘设备可视页面’ } 查看ips所属mac nbtstat -a 10.87.236.60 获取容器名称 hostName In…...

本省第一所!新大学,揭牌!

9月26日&#xff0c;海南艺术职业学院举行揭牌仪式&#xff0c;标志着海南省第一所公办艺术类高等职业院校正式揭牌成立。海南省旅文厅党组成员、副厅长刘成出席揭牌仪式&#xff0c;省教育厅党组成员、副厅长邢孔政在揭牌仪式上宣读省人民政府同意设立海南艺术职业学院的批复。…...

企业微信(企微)审批与影刀RPA结合

企业微信审批与影刀RPA结合 效果先看视频&#xff1a; 影刀与企业微信审批结合 具体步骤&#xff1a; 1、登录企微管理后台&#xff0c;新建一个审批流。 添加模板→自定义模板&#xff0c;根据需求添加审批节点。 添加完之后&#xff0c;回到审批界面&#xff0c;可以看…...

新手教学系列——用 VSCode 实现高效远程开发

随着软件开发环境日益复杂,远程开发已成为许多开发者的日常工作方式。尤其当项目需要直接在服务器上运行或本地计算资源有限时,能够使用一款便捷、强大的工具至关重要。在众多 IDE 中,VSCode 因其轻量、灵活且支持丰富插件,成为远程开发的理想选择。本文将详细介绍如何通过…...

[uni-app]小兔鲜-04推荐+分类+详情

热门推荐 新建热门推荐组件, 动态设置组件的标题 <template><!-- 推荐专区 --><view class"panel hot"><view class"item" v-for"item in list" :key"item.id">... ...<navigator hover-class"none&…...

PHP人才机遇桥梁招聘求职全能系统小程序源码

人才机遇桥梁 —— 招聘求职全能系统全解析 &#x1f4bc;&#x1f680; &#x1f309; 搭建人才与机遇的桥梁 在这个竞争激烈的职场环境中&#xff0c;找到一份心仪的工作或招募到合适的人才&#xff0c;往往不是一件容易的事。但幸运的是&#xff0c;我们有了“人才机遇桥梁…...

计算机毕业设计Hadoop+Spark抖音可视化 抖音舆情监测 预测算法 抖音爬虫 抖音大数据 情感分析 NLP 自然语言处理 Hive 机器学习 深度学习

Python抖音可视化开题报告 一、研究背景与意义 随着移动互联网的迅猛发展&#xff0c;短视频平台如抖音已成为人们日常生活中不可或缺的一部分。抖音以其独特的算法和内容推荐机制&#xff0c;吸引了数以亿计的用户。然而&#xff0c;随着用户规模的不断扩大&#xff0c;如何…...

Linux 学习 awk 和sed 命令使用

awk 命令 awk 是一种处理文本文件的语言&#xff0c;是一个强大的文本分析工具。 awk 通过提供编程语言的功能&#xff0c;如变量、数学运算、字符串处理等&#xff0c;使得对文本文件的分析和操作变得非常灵活和高效。 之所以叫 awk 是因为其取了三位创始人 Alfred Aho&#x…...

双端搭建个人博客

1. 准备工作 确保你的两个虚拟机都安装了以下软件: 虚拟机1(Web服务器): Apache2, PHP虚拟机2(数据库服务器): MariaDB2. 安装步骤 虚拟机1(Web服务器) 安装Apache2和PHP 更新系统包列表: sudo apt update安装Apache2: sudo apt install apache2 -y安装PHP及其Apac…...

PHP 面向对象编程

PHP 面向对象编程 PHP 是一种流行的服务器端脚本语言&#xff0c;广泛用于 web 开发。它支持多种编程范式&#xff0c;包括面向对象编程&#xff08;OOP&#xff09;。面向对象编程是一种编程风格&#xff0c;它使用“对象”来设计软件&#xff0c;其中对象是数据和行为的集合…...

应急响应(1)-同事电脑

一、现象 重要时间节点&#xff0c;同事反馈桌面有鼠标移动、随机断网&#xff1b;发现登录账户多了一个&#xff0c;由于电脑长时间没有更改过密码&#xff0c;导致忘记密码无法登录。随机联系进行应急处理。 二、排查 2.1、密码重置/删除 由于同事忘记密码导致无法进行登录…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

Java编程之桥接模式

定义 桥接模式&#xff08;Bridge Pattern&#xff09;属于结构型设计模式&#xff0c;它的核心意图是将抽象部分与实现部分分离&#xff0c;使它们可以独立地变化。这种模式通过组合关系来替代继承关系&#xff0c;从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10+pip3.10)

第一篇&#xff1a;Liunx环境下搭建PaddlePaddle 3.0基础环境&#xff08;Liunx Centos8.5安装Python3.10pip3.10&#xff09; 一&#xff1a;前言二&#xff1a;安装编译依赖二&#xff1a;安装Python3.10三&#xff1a;安装PIP3.10四&#xff1a;安装Paddlepaddle基础框架4.1…...

OCR MLLM Evaluation

为什么需要评测体系&#xff1f;——背景与矛盾 ​​ 能干的事&#xff1a;​​ 看清楚发票、身份证上的字&#xff08;准确率>90%&#xff09;&#xff0c;速度飞快&#xff08;眨眼间完成&#xff09;。​​干不了的事&#xff1a;​​ 碰到复杂表格&#xff08;合并单元…...

跨平台商品数据接口的标准化与规范化发展路径:淘宝京东拼多多的最新实践

在电商行业蓬勃发展的当下&#xff0c;多平台运营已成为众多商家的必然选择。然而&#xff0c;不同电商平台在商品数据接口方面存在差异&#xff0c;导致商家在跨平台运营时面临诸多挑战&#xff0c;如数据对接困难、运营效率低下、用户体验不一致等。跨平台商品数据接口的标准…...