Spring Boot 开发 -- 过滤器与拦截器详解

引言

在Web开发中,经常需要对请求进行预处理或在响应后进行后处理,Spring Boot提供了过滤器和拦截器两种机制来实现这一需求。虽然它们都可以用来处理HTTP请求和响应,但在使用场景、执行顺序和配置方式上存在明显的差异。本文将详细讲解Spring Boot中过滤器和拦截器的概念、使用方法和它们之间的区别。

一、过滤器(Filter)的配置

方式 一 :使用spring boot提供的FilterRegistrationBean注册Filter

1. 实现Filter接口:

创建一个类并实现javax.servlet.Filter接口,重写doFilter方法。

public class LogCostFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {long start = System.currentTimeMillis();filterChain.doFilter(servletRequest,servletResponse);System.out.println("Execute cost="+(System.currentTimeMillis()-start));}@Overridepublic void destroy() {}
}

2. 注册自定义Filter

在Spring boot中,我们需要FilterRegistrationBean来完成配置。其实现过程如下:

@Configuration
public class FilterConfig {@Beanpublic FilterRegistrationBean registFilter() {FilterRegistrationBean registration = new FilterRegistrationBean();registration.setFilter(new LogCostFilter());registration.addUrlPatterns("/*");registration.setName("LogCostFilter");registration.setOrder(1);return registration;}}

方式二:使用原生servlet注解定义Filter

除了通过 FilterRegistrationBean 来配置以外,还有一种更直接的办法,直接通过注解就可以完成了:

@WebFilter(urlPatterns = "/*", filterName = "logFilter2")
public class LogCostFilter2 implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {long start = System.currentTimeMillis();filterChain.doFilter(servletRequest, servletResponse);System.out.println("LogFilter2 Execute cost=" + (System.currentTimeMillis() - start));}@Overridepublic void destroy() {}
}

这里直接用@WebFilter就可以进行配置,同样,可以设置url匹配模式,过滤器名称等。这里需要注意一点的是**@WebFilter这个注解是Servlet3.0的规范**,并不是Spring boot提供的。除了这个注解以外,我们还需在配置类中加另外一个注解:@ServletComponetScan,指定扫描的包。

@SpringBootApplication
@MapperScan("com.dz.blog.dao")
@ServletComponentScan("com.dz.blog.filters")
public class Application {public static void main(String[] args) throws Exception {SpringApplication.run(Application.class, args);}
}

二、拦截器(Interceptor)的配置

拦截器是Spring MVC框架中的一部分,用于在请求处理前后执行一些操作,如权限验证、日志记录等。拦截器通过实现HandlerInterceptor接口继承HandlerInterceptorAdapter类来实现。

我们使用拦截器来实现上面同样的功能,记录请求的执行时间。

1. 首先我们实现拦截器类:

public class LogCostInterceptor implements HandlerInterceptor {long start = System.currentTimeMillis();@Overridepublic boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {// 请求前处理逻辑  start = System.currentTimeMillis();// 如果返回false,则请求终止return true;}@Overridepublic void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {// 请求后处理逻辑System.out.println("Interceptor cost="+(System.currentTimeMillis()-start));}@Overridepublic void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {// 整个请求处理完毕后调用  }
}

2. 注册Interceptor:

在配置类中通过实现WebMvcConfigurer接口并重写addInterceptors方法来注册拦截器。

@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LogCostInterceptor()).addPathPatterns("/**");super.addInterceptors(registry);}
}

三、过滤器和拦截器的区别

  1. 参考标准
  • 过滤器是 JavaEE 的标准,依赖于 Servlet 容器,生命周期也与容器一致,利用这一特性可以在销毁时释放资源或者数据入库。
  • 拦截器是SpringMVC中的内容,依赖于web框架,通常用于验证用户权限或者记录日志,但是这些功能也可以利用 AOP 来代替。
  1. 实现方式
  • 过滤器是基于回调函数实现,无法注入 ioc 容器中的 bean。

  • 拦截器是基于反射来实现,因此拦截器中可以注入 ioc 容器中的 bean,例如注入 Redis 的业务层来验证用户是否已经登录。

  • 过滤器(Filter) :可以拿到原始的http请求,但是拿不到你请求的控制器和请求控制器中的方法的信息。

  • 拦截器(Interceptor):可以拿到请求的控制器和方法,却拿不到请求方法的参数。

  • 切片(Aspect): 可以拿到方法的参数,但是却拿不到http请求和响应的对象

在这里插入图片描述
参考文献:
https://developer.aliyun.com/article/1271920

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/20436.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode 2928.给小朋友们分糖果 I:Java提交的运行时间超过了61%的用户

【LetMeFly】2928.给小朋友们分糖果 I:Java提交的运行时间超过了61%的用户 力扣题目链接:https://leetcode.cn/problems/distribute-candies-among-children-i/ 给你两个正整数 n 和 limit 。 请你将 n 颗糖果分给 3 位小朋友,确保没有任何…

易语言贪吃蛇游戏(附带源码)

易语言贪吃蛇游戏 效果图源码说明源码领取下期更新预报 效果图 源码说明 本源码用易语言来编写,供大家研究,保留版权,谢谢! 源码领取 易语言贪吃蛇游戏源码领取地址:https://www.123pan.com/s/ji8kjv-TKPU3.html提取…

Oracle中rman的增量备份使用分享

继上次使用RMAN的全量备份和异机还原以后,开始研究一下增量备份和还原的方法。相比于全量RMAN的备份还原,增量的备份还原就相对简单。本实践教程直接上操作,还是回归到一个问题,就是关于两个数据库创建时候,必须保持or…

泄漏libc基地址

拿libc基地址 方法一:格式化字符串 格式化字符串,首先确定输入的 AAAA 在栈上的位置(x)。使用 elf.got[fun] 获得got地址。利用格式化字符串,构造payload泄漏got地址处的值,recv接受到的字符串中&#xf…

linux部署运维1——centos7.9离线安装部署web或java项目所需的依赖环境,包括mysql8.0,nginx1.20,redis5.0等工具

在实际项目部署运维过程中,如果是云服务器,基本安装项目所需的依赖环境都是通过yum联网拉取网络资源实现自动化安装的;但是对于一些特殊场合,在没有外部网络的情况下,就无法使用yum命令联网操作,只能通过编…

网络报文协议头学习

vxlan:就是通过Vxlan_header头在原始报文前面套了一层UDPIP(4/6)Eth_hdr 需求背景:VXLAN:简述VXLAN的概念,网络模型及报文格式_vxlan报文格式-CSDN博客 如果服务器作为VTEP,那从服务器发送到接…

jmeter之MD5加密请求秒杀接口教程

前言: 有时候在项目中,需要使用MD5加密的方法才可以登录,或者在某一个接口中遇到 登录获取token后才可以进行关联,下面介绍下遇到的常见使用 一、第一种方法:使用jmeter自带的函数助手digest 选择工具,选…

并查集拓展(扩展域并查集)

事实证明,扩展域并查集应该在带权并查集前面讲的,因为比较好理解,而且回过头看带权并查集可能也会更轻松一些。 https://www.luogu.com.cn/problem/P1892https://www.luogu.com.cn/problem/P1892 题目描述 现在有 𝑛 个人&…

算法解析——单身狗问题

欢迎来到博主的专栏:算法解析 博主ID代码小豪 文章目录 什么是单身狗问题leetcode_136——只出现一次的数字I使用位运算解决单身狗问题。 leetcode_137——只出现一次的数字II统计二进制数解决单身狗问题leetcode_260 只出现一次数字III分区域按位异或解决问题。 总…

C语言:如何写文档注释、内嵌注释、行块注释?

技术答疑流程 扫描二维码,添加个人微信;支付一半费用,获取答案;如果满意,则支付另一半费用; 知识点费用:10元 项目费用:如果有项目任务外包需求,可以微信私聊

【scikit-learn009】异常检测系列:单类支持向量机(OC-SVM)实战总结(看这篇就够了,已更新)

1.一直以来想写下机器学习训练AI算法的系列文章,作为较火的机器学习框架,也是日常项目开发中常用的一款工具,最近刚好挤时间梳理、总结下这块儿的知识体系。 2.熟悉、梳理、总结下scikit-learn框架OCSVM模型相关知识体系。 3.欢迎批评指正,欢迎互三,跪谢一键三连! 4.欢迎…

Vue3实战笔记(57)—一键换肤:在Vuetify中打造个性化主题切换体验

文章目录 前言一键换肤总结 前言 在当今追求极致用户体验的时代,为应用程序提供个性化的主题切换功能已经成为提升用户满意度和留存率的关键因素之一。Vuetify,作为基于Vue.js的流行前端框架,以其丰富的组件库和高度可定制性,为开…

day05-多任务-正则-装饰器

一、多任务 1-进程和线程 进程是操作系统分配资源的最小单元 线程执行程序的的最小单元 线程依赖进程,可以获取进程的资源 一个程序执行 先要创建进程分配资源,然后使用线程执行任务 默认情况下一个进程中有一个线程 2-多任务介绍 运行多个进程或线程执…

民国漫画杂志《时代漫画》第38期.PDF

时代漫画38.PDF: https://url03.ctfile.com/f/1779803-1248636380-dd7daa?p9586 (访问密码: 9586) 《时代漫画》的杂志在1934年诞生了,截止1937年6月战争来临被迫停刊共发行了39期。 ps: 资源来源网络!

CATIA进阶操作——创成式曲面设计入门(1)线架设计,三维点、直线、平面、曲线

目录 引出三维空间点生成三维直线三维平面三维曲线总结异形弹簧新建几何体草图编辑,画一条样条线进行扫掠,圆心和半径画出曲面上的螺旋线再次选择扫掠,圆心和半径 其他自定义信号和槽1.自定义信号2.自定义槽3.建立连接4.进行触发 自定义信号重…

【YOLOv5/v7改进系列】引入ODConv——即插即用的卷积块

一、导言 提出了一种称为全维度动态卷积(ODConv)的新颖设计,旨在克服当前动态卷积方法的局限性并提升卷积神经网络(CNN)的性能。以下是该论文提出的全维度动态卷积设计的优点和存在的缺点分析: 优点: 增强特征学习能力: ODConv通…

【UML用户指南】-04-从代码到UML的关键抽象

1、关键抽象 声明了一个名为paint的操作,它的实现调用名为drawString的另一个操作,drawString操作负责在指定的位置上打印“Hello,World!”。在通常的面向对象的方式下,drawString是一个名称为g的参数上的一个操作,g的类型是类Gr…

VMWare下安装Linux虚拟机(图文)

大家好,在当今科技发展迅速的时代,虚拟化技术在企业和个人用户中变得越来越普遍。VMware作为一款领先的虚拟化软件,为用户提供了在单一物理计算机上运行多个操作系统的能力,为开发、测试和运维等任务提供了便利。在这篇文章中&…

打开C语言常用的内存函数大门(三) —— memset()函数(内含讲解用法和模拟实现)

文章目录 1. 前言2. memset函数2.1 memset函数原型2.2 memset函数参数的介绍2.3 memset函数的使用演示 3. memset函数的模拟实现4. 总结 1. 前言 哈喽,我们又见面了。通过前面两个内存函数(memcpy、memmove函数)讲解的锤炼后,对如何解析一个自己从来没有…

【TB作品】msp430f5529单片机墨水屏,口袋板,tmp421温度,温控风扇

文章目录 一、扬声器模块介绍二、驱动介绍三、程序介绍四、全部代码下载 msp430f5529d单片机墨水屏,口袋板,tmp421温度,温控风扇 基本要求:高于20度开转,温度越高转速越快,高于40度风扇停转,温…