SpringBoot自定义拦截器interceptor使用详解
Spring Boot拦截器Intercepter详解
Intercepter是由Spring提供的Intercepter拦截器,主要应用在日志记录、权限校验等安全管理方便。
使用过程
1.创建自定义拦截器,实现HandlerInterceptor接口,并按照要求重写指定方法
HandlerInterceptor接口源码:
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接口提供了三个default方法,这三个方法作用不同,用户想要自定义个一个指定拦截规则的拦截器,需要重写其中一个或者多个方法,这三个方法作用如下:
- perHandle:preHandle方法的作用是,当请求在进入controller之前拦截请求,对请求进行预处理,比如登录验证(cookie,token,referer)或者单点登录cookie解析都可以在这方法中进行。该方法的返回值,如果返回true,表示放行至controller业务层,如果false,表示请求非法,结束请求并返回错误信息。
- postHandler:postHandle方法是在请求被controller处理完但是还未传递到业务模板进行渲染拦截,即controller处理完,返回ModelAndView 之前执行该方法,可以操控ModelAndView的值;所以该方法多了一个参数,ModelAndView,这个参数包含了controller处理完后需要传递的Model参数,因此,我们可以在该方法通过ModelAndView对象对返给前端的额视图做一定的修改。
- afterCompletion:afterCompletion方法作用就是做些收尾工作,在ModelAndView返回前端进行渲染后执行,比如有时候我们需要把每个线程的局部变量(如User信息)放入到TheradLocal中,为了防止内存泄露,在最后需要清除ThreadLocal的内容,此操作就可以放在该方法中执行。
自定义一个获取并返回某个静态资源的内容已整个请求所花费时间的时间拦截器
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class MyInterceptor implements HandlerInterceptor {private static final Logger LOGGER = LoggerFactory.getLogger(MyInterceptor.class);private static final ThreadLocal<Long> START_THREAD_LOCAL = new ThreadLocal<>();@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {String uri = request.getRequestURI();LOGGER.info(uri + " preHandle");Long startTime = System.currentTimeMillis(); //获取开始时间START_THREAD_LOCAL.set(startTime); //线程绑定变量(该数据只有当前请求的线程可见)return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {String uri = request.getRequestURI();LOGGER.info(uri + " postHandle");Long startTime = START_THREAD_LOCAL.get();//得到线程绑定的局部变量(开始时间)Long endTime = System.currentTimeMillis(); //2、结束时间Long time = endTime - startTime;LOGGER.info("http request all time: " + time + "ms");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,Exception ex) throws Exception {String uri = request.getRequestURI();LOGGER.info(uri + " afterCompletion");if (START_THREAD_LOCAL != null) {START_THREAD_LOCAL.remove(); // 移除ThreadLocal中的局部变量}}
}
2.添加配置类,实现WebMvcController接口,并添加@Configuration注解,在配置类中,重写addIntercepters方法,添加要拦截的url以及url白名单(需要排除拦截的url)
WebMvcConfigurer源码:
public interface WebMvcConfigurer {default void configurePathMatch(PathMatchConfigurer configurer) {}default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {}default void configureAsyncSupport(AsyncSupportConfigurer configurer) {}default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {}default void addFormatters(FormatterRegistry registry) {}default void addInterceptors(InterceptorRegistry registry) {}default void addResourceHandlers(ResourceHandlerRegistry registry) {}default void addCorsMappings(CorsRegistry registry) {}default void addViewControllers(ViewControllerRegistry registry) {}default void configureViewResolvers(ViewResolverRegistry registry) {}default void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {}default void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {}default void configureMessageConverters(List<HttpMessageConverter<?>> converters) {}default void extendMessageConverters(List<HttpMessageConverter<?>> converters) {}default void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {}default void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {}@Nullabledefault Validator getValidator() {return null;}@Nullabledefault MessageCodesResolver getMessageCodesResolver() {return null;}
}
根据源码可以看出,WebMvcConfigurer提供了多个方法,并且也都是default方法,也是根据我们自定义配置,重写其中一个或者多个方法,这里就介绍两个常用的方法:
- addInterceptors:从该方法名就可以了解到该方法是添加拦截器,即将拦截器交给IOC去执行,拦截器需要拦截的路径以及需要排除拦截的路径在该方法中配置。
- addResourceHandlers:该方法的作用是配置静态资源路径。即某些请求需要读取某个路径下的静态资源内容,需要配置该静态资源的路径,通过该方法可以统一给这些请求配置指定静态资源路径 。
实例:
import com.eureka.intercrpotor.MyInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class InterceptorConfig implements WebMvcConfigurer {@Beanpublic MyInterceptor myInterceptor() {return new MyInterceptor();}@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(myInterceptor()) // 添加拦截器.addPathPatterns("/**") // 配置拦截请求url( ** 表示拦截所有请求url).excludePathPatterns("/hello"); // 排除某些不需要拦截的请求url(即带有/hello请求不会被拦截)}@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/**") // 配置需要添加静态资源的请求url.addResourceLocations("classpath:/mydata/"); //配置静态资源路径}
}
测试:
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class TestController {@GetMapping("/test/interceptor")public ResponseEntity<String> testInterceptor() {return ResponseEntity.ok("successful");}
}
静态资源:
启动项目后访问 localhost:60011/test/interceptor:
控制台打印的日志:
我们再通过url访问静态资源请求 localhost:60011/test.jpg
相关文章:

SpringBoot自定义拦截器interceptor使用详解
Spring Boot拦截器Intercepter详解 Intercepter是由Spring提供的Intercepter拦截器,主要应用在日志记录、权限校验等安全管理方便。 使用过程 1.创建自定义拦截器,实现HandlerInterceptor接口,并按照要求重写指定方法 HandlerInterceptor接口源码&am…...

AI抠图使用指南:Stable Diffusion WebUI Rembg实用技巧
抠图是图像处理工具的一项必备能力,可以用在重绘、重组、更换背景等场景。最近我一直在探索 Stable Diffusion WebUI 的各项能力,那么 SD WebUI 的抠图能力表现如何呢?这篇文章就给大家分享一下。 安装插件 作为一个生成式AI,SD…...

gitlab-Runner搭建
root wget https://packages.gitlab.com/runner/gitlab-runner/packages/fedora/29/gitlab-runner-12.6.0-1.x86_64.rpm/download.rpm rpm -ivh download.rpm ---- 安装 rpm -Uvh download.rpm -----更新升级 然后运行: gitlab-runner register --url https://git…...

【ChatGPT 指令大全】销售怎么借力ChatGPT提高效率
目录 销售演说 电话销售 产出潜在客户清单 销售领域计划 销售培训计划 总结 随着人工智能技术的不断进步,我们现在有机会利用ChatGPT这样的智能助手来改进我们的销售工作。在接下来的时间里,我将为大家介绍如何运用ChatGPT提高销售效率并取得更好的…...

【Spring】-Spring项目的创建
作者:学Java的冬瓜 博客主页:☀冬瓜的主页🌙 专栏:【Framework】 主要内容:创建spring项目的步骤:先创建一个maven项目,再在pom.xml中添加spring框架支持,最后写一个启动类。 文章目…...

SQL | 使用通配符进行过滤
6-使用通配符进行过滤 6.1-LIKE操作符 前面介绍的所有操作符都是通过已知的值进行过滤,或者检查某个范围的值。但是如果我们想要查找产品名字中含有bag的数据,就不能使用前面那种过滤情况。 利用通配符,可以创建比较特定数据的搜索模式。 …...
make: *** [Makefile:719: ext/openssl/openssl.lo] Error 1
在ubuntu系统上编译安装PHP7.4.33时,会报错如下 make: *** [Makefile:719: ext/openssl/openssl.lo] Error 1 原因分析:这个错误提示的意思是PHP配置过程中缺少OpenSSL库文件,因此在编译过程中出现了问题;Ubuntu 22.04 中openss…...

Android Studio实现简单ListView
效果图 MainActivity package com.example.listviewtest;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle; import android.widget.ListView;import com.example.listviewtest.adapter.PartAdapter; import com.example.listviewtest.bean.PartB…...

【设计模式】模板模式
什么是模板模式? 模板方法模式(Template Method Pattern),又叫模板模式(Template Pattern),在一个抽象类公开定义了执行它的方法的模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行…...

配置docker和复现
1.Nginx环境搭建 选择centos7来进行安装 1.1 创建Nginx的目录并进入 mkdir /soft && mkdir /soft/nginx/ cd /soft/nginx/ 1.2 下载Nginx的安装包,可以通过FTP工具上传离线环境包,或者通过wget命令在线获取安装包 wget https://nginx.org/down…...

Qt应用开发(基础篇)——工具箱 QToolBox
一、前言 QToolBox类继承于QFrame,QFrame继承于QWidget,是Qt常用的基础工具部件。 框架类QFrame介绍 QToolBox工具箱类提供了一列选项卡窗口,当前项显示在当前选项卡下面,适用于分类浏览、内容展示、操作指引这一类的使用场景。 二…...

地理测绘基础知识(1) 坐标系经纬度与ECEF直角坐标的基本换算
经纬度与ECEF直角坐标的基本换算 我们目前最常用的全球坐标系是WGS-84坐标系,各种手机、地图基本用经纬度来标记位置。然而,经纬度对于空间的计算是很复杂的,需要很多三角函数操作。平面直角坐标系利用向量的运算,可以非常方便的…...

【UE4 RTS】08-Setting up Game Clock
前言 本篇实现的效果是在游戏运行后能够记录当前的游戏时间(年月日时分秒),并且可以通过修改变量从而改变游戏时间进行的快慢。 效果 步骤 1. 在Blueprints文件夹中新建如下两个文件夹,分别命名为“GameSettings”、“Player”…...

百度chatgpt内测版
搜索AI伙伴 申请到了百度的chatgpt: 完整的窗口布局: 三个哲学问题: 灵感中心: 请做一副画,一个渔夫,冬天,下着大雪,在船上为了一家的生计在钓鱼,远处的山上也都是白雪&a…...

[GAN] 使用GAN网络进行图片生成的“调参人”入门指南——生成向日葵图片
[GAN] 使用GAN网络进行图片生成的“炼丹人”日志——生成向日葵图片 文章目录 [GAN] 使用GAN网络进行图片生成的“炼丹人”日志——生成向日葵图片1. 写在前面:1.1 应用场景:1.2 数据集情况:1.3 实验原理讲解和分析(简化版&#x…...

(十)人工智能应用--深度学习原理与实战--模型的保存与加载使用
目的:将训练好的模型保存为文件,下次使用时直接加载即可,不必重复建模训练。 神经网络模型训练好之后,可以保存为文件以持久存储,这样下次使用时就不重新建模训练,直接加载就可以。TensorfLow提供了灵活的模型保存方案,既可以同时保存网络结构和权重(即保存全模型),也可…...
Java“牵手”1688商品详情页面数据获取方法,1688API实现批量商品数据抓取示例
背景:1688商城是一个网上购物平台,售卖各类商品,包括服装、鞋类、家居用品、美妆产品、电子产品等。要获取1688商品详情数据,您可以通过开放平台的接口或者直接访问1688商城的网页来获取商品详情信息。以下是两种常用方法的介绍&a…...
Docker_docker runContainerd
docker run-Containerd docker run -it 运行容器交互式方式启动守护进程方式启动其他命令 docker部署nginx服务k8s废弃docker原因安装和配置containerdcontainerd常用命令 docker run -it 运行容器 交互式方式启动 # 以交互式方式启动并进入容器 docker run --namehello -it …...
python中常见的矩阵变换总结
利用python做数据处理和分析过程中,如在开展机器学习的数据预处理、数据格式转换等等,不可避免的会涉及到各种矩阵变换,其中使用最多的就是numpy下的矩阵变换,以下是日常用到的一些矩阵变换总结,主要有矩阵中数据类型的…...

Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...

UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...