SpringBoot十二、SpringBoot系列web篇之过滤器Filte详解

一、前言

JavaWeb三大组件Servlet、Filter、Listener,其中之一便是过滤器Filter。

其实,Filter我们平常用的不多,一般多为项目初期搭建web架构的时候使用,后面用的就少了,在日常业务开发中不太可能碰到需要手写Filter的场景。

下面我们两带着以下几个问题,学习一下SpringBoot中怎样使用Filter。

  • 在SpringBoot中如何配置Filter过滤器?
  • 过滤器Filter在SpringBoot中的执行顺序是怎样的?
  • 如何在SpringBoot中使用自定义的Filter过滤器?

 

二、Filter过滤器

1. Filter简介

Filter,过滤器,属于Servlet规范,并不是Spring独有的。Filter在web服务器中,位于浏览器与Servlet之间。
其作用是拦截一个请求,做一些业务逻辑操作,比如:登录校验、统一编码处理、敏感字符处理等。

 

2. 简介Filter流程

Filter在web服务器中,位于浏览器与Servlet之间,当请求进入web服务器时进行预处理,然后交Servlet,Servlet处理完成后,将响应传递给Filter进行后处理,之后才到达客户端的浏览器。
有时会设置多个Filter过滤器,经过Filter1处理后进入Filter2,之后也许还有Filter3,这样就形成了Filter链。而在Filter链中,只要有一处不放行,后续的检测都不会发生。
过滤器通过后,就可以访问web服务器上的资源。
在这里插入图片描述

 

三、自定义Filter过滤器

1. 引入web依赖

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
</dependencies>

 

2. 自定义过滤器

第1步:创建过滤器类
定义一个类MyFilter,实现 Filter 接口,并重写其所有方法。

第2步:配置过滤器
在自定义过滤器MyFilter类上加 @WebFilter 注解,配置拦截资源的路径。

public class MyFilter implements Filter {@Override //初始化方法, 只调用一次public void init(FilterConfig filterConfig) throws ServletException {System.out.println("init 初始化方法执行了");}@Override //拦截到请求之后调用, 调用多次public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {System.out.println("Demo 拦截到了请求...放行前逻辑");//放行chain.doFilter(request,response);}@Override //销毁方法, 只调用一次public void destroy() {System.out.println("destroy 销毁方法执行了");}
}

说明:

  • init方法:过滤器的初始化方法。在web服务器启动> 的时候会自动的创建Filter过滤器对象,在创建过滤> 器对象的时候会自动调用init初始化方法,这个方法> 只会被调用一次。
  • doFilter方法:这个方法是在每一次拦截到请求之后都会被调用,所以这个方法是会被调用多次的,每拦截到一次请求就会调用一次doFilter()方法。
  • destroy方法: 是销毁的方法。当我们关闭服务器的时候,它会自动的调用销毁方法destroy,而这个销毁方法也只会被调用一次。

 

3. Filter的配置

在定义完Filter之后,Filter其实并不会生效,并不会被SpringBoot加载,还需要完成Filter的配置。

SpringBoot项目中,配置Filter生效有三种常见方式(注解和配置Bean):

  • @WebFilter(如果存在多个Filter,则不推荐;单个Filter推荐。)
  • FilterRegistrationBean注册方式
  • 在web.xml中配置

 

3.1 方式一、@WebFilter注解方式

Filter的配置注解方式非常简单:

  1. 只需要在自定义过滤器MyFilter类上添加一个注解:@WebFilter,并指定属性urlPatterns(通过这个属性指定过滤器要拦截哪些请求);
  2. 在启动类上面加上一个注解@ServletComponentScan,通过这个@ServletComponentScan注解来开启SpringBoot项目对于Servlet组件的支持。

注解方式加载-自定义过滤器:

@WebFilter(urlPatterns = "/*") //配置过滤器要拦截的请求路径( /* 表示拦截浏览器的所有请求 )
public class MyFilter implements Filter {@Override //初始化方法, 只调用一次public void init(FilterConfig filterConfig) throws ServletException {System.out.println("init 初始化方法执行了");}@Override //拦截到请求之后调用, 调用多次public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {System.out.println("Demo 拦截到了请求...放行前逻辑");//放行chain.doFilter(request,response);}@Override //销毁方法, 只调用一次public void destroy() {System.out.println("destroy 销毁方法执行了");}
}

启动类上加@ServletComponentScan注解:

@ServletComponentScan
@SpringBootApplication
public class TliasWebManagementApplication {public static void main(String[] args) {SpringApplication.run(TliasWebManagementApplication.class, args);}
}

注意: 注解方式配置Filter会有个小问题,即指定Filter的优先级比较麻烦,如果存在多个FIlter,则无法指定优先级。这个问题后续说明!!!

 

3.2 @WebFilter注解说明
  • @WebFilter注解属于Servlet3+,与Spring也没有什么关系。

  • @WebFilter注解常用属性如下,其中urlPatterns最为常用,表示这个filter适用于哪些url请求(默认场景下全部请求都被拦截)。

WebFilter常用属性:

属性名类型描述
filterNameString指定过滤器的 name 属性,等价于 <filter-name>
valueString[]该属性等价于 urlPatterns 属性。但是两者不应该同时使用。
urlPatternsString[]指定一组过滤器的 URL 匹配模式。等价于 <url-pattern> 标签。比如:/*指的是所有请求。
servletNamesString[]指定过滤器将应用于哪些 Servlet。取值是 @WebServlet 中的 name 属性的取值,或者是 web.xml 中<servlet-name> 的取值。
dispatcherTypesDispatcherType指定过滤器的转发模式。具体取值包括:ASYNC、ERROR、FORWARD、INCLUDE、REQUEST。
initParamsWebInitParam[]指定一组过滤器初始化参数,等价于 <init-param> 标签。
asyncSupportedboolean声明过滤器是否支持异步操作模式,等价于 <async-supported> 标签。
descriptionString该过滤器的描述信息,等价于 <description> 标签。
displayNameString该过滤器的显示名,通常配合工具使用,等价于 <display-name> 标签。

 
拦截路径(urlPatterns)说明:

拦截路径urlPatterns值含义
拦截具体路径/login只有访问 /login 路径时,才会被拦截
目录拦截/liupy/*访问/liupy下的所有资源,都会被拦截
拦截所有/*访问所有资源,都会被拦截

 

3.3 方式二、FilterRegistrationBean 注册方式

下面是使用包装bean注册方式。
首先需要新建一个配置类MybootWebConfig,该配置类中定义一个Bean,在该bean中注册自定义的过滤器。

自定义过滤器:

public class MyFilter implements Filter {@Override //初始化方法, 只调用一次public void init(FilterConfig filterConfig) throws ServletException {System.out.println("init 初始化方法执行了");}@Override //拦截到请求之后调用, 调用多次public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {System.out.println("Demo 拦截到了请求...放行前逻辑");//放行chain.doFilter(request,response);}@Override //销毁方法, 只调用一次public void destroy() {System.out.println("destroy 销毁方法执行了");}
}

自定义配置文件:

@Configuration
public class MybootWebConfig implement WebMvcConfig {
public MybootWebConfig(){}
@Bean
public FilterRegistrationBean<Filter> orderFilter() {FilterRegistrationBean<Filter> filter = new FilterRegistrationBean<>();filter.setName("reqFilter");//注册自定义过滤器filter.setFilter(new MyFilter()); //MyFilter是自定义过滤器// 指定优先级filter.setOrder(-1);filter.addUrlPatterns(new String[]{"/*"});return filter;
}
}

 

四、过滤器链

过滤器链:指的是在一个web应用程序当中,可以自定义并配置多个过滤器,多个过滤器就形成了一个过滤器链。

比如:在我们web服务器当中,定义了两个过滤器,这两个过滤器就形成了一个过滤器链。而这个链上的过滤器在执行的时候会一个一个的执行,会先执行第一个Filter,放行之后再来执行第二个Filter,如果执行到了最后一个过滤器放行之后,才会访问对应的web资源。

访问完web资源之后,按照我们刚才所介绍的过滤器的执行流程,还会回到过滤器当中来执行过滤器放行后的逻辑,而在执行放行后的逻辑的时候,顺序是反着的。先要执行过滤器2放行之后的逻辑,再来执行过滤器1放行之后的逻辑,最后在给浏览器响应数据。

在这里插入图片描述

 

五、Filter链的处理顺序

5.1. 指定FIlter顺序遇到的问题

上面我们说过,如果web项目中存在多个Filter过滤器(即过滤器链),注解方式在指定Filter过滤器的执行顺序时,很难控制执行顺序。

如果设置了多个Filter,如何设置多个Filter之间的处理顺序?有以下两种做法:

  • 注解方式(不推荐):@Order(1)注解无法明确控制不同Filter的执行顺序,此时会按Filter类名字母顺序进行处理。如AFilter会先于BFilter执行; 如果只有一个Filter过滤器,则推荐,因为配置简单。
  • web.xml方式(推荐):当请求到来时按照<filter-mapping></filter-mapping>中的顺序,从上到下进行处理。 当响应返回时,按照<filter-mapping></filter-mapping>中,从下到上进行处理(逆序)。
  • 配置类中bean注册方式(推荐)。在配置类中,注册自定义Filter过滤器时,可以设置顺序:myFilter.setOrder(-1)。

 

5.2. 指定FIlter顺序演示

如下为自定义FIlter过滤器:

@Order(2)
@WebFilter
public class AnyFilter implements Filter, Ordered {...
}@Order(1)
@WebFilter
public class ReqFilter implements Filter, Ordered {...
}public class OrderFilter implements Filter {
}/** 启动类 */
@ServletComponentScan
@SpringBootApplication
public class Application {/** 注册自定义过滤器 OrderFilter*/@Beanpublic FilterRegistrationBean<OrderFilter> orderFilter() {FilterRegistrationBean<OrderFilter> filter = new FilterRegistrationBean<>();filter.setName("orderFilter");filter.setFilter(new OrderFilter());//设定优先级filter.setOrder(-1);return filter;}public static void main(String[] args) {SpringApplication.run(Application.class);}
}
  • 通过实际测试,@Order注解没有用,继承 Ordered接口也没有用,再不考虑web.xml配置的场景下,只能通过在注册Bean的时候指定优先级。
  • 如上实例:三个Filter,两个通过@WebFilter注解方式注册,一个通过FilterRegistrationBean方式注册。

结论:

  1. 自定义Filter过滤器的优先级为:OrderFiler > AnyFilter >ReqFilter ;
  2. 显然,OrderFilter过滤器的优先级最高,因为OrderFilter是通过FilterRegistrationBean方式注册,并且手动注册时,并设置优先级为-1,所以先执行。
  3. AnyFilter 、ReqFilter 这两个自定义过滤器,都是注解方式,AnyFilter 设置为2,ReqFilter 设置为1,但是结果却是AnyFilter 优先级大于ReqFilter ,说明@Order注解不能指定Filter的优先级。
  4. 采用@WebFilter注解方式使用过滤器时,会按照 “自定义过滤器Filter类名字母先后顺序” 进行处理, 所以AnyFilter 会先于ReqFilter 执行。

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

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

相关文章

Java实现飞机射击游戏:从设计到完整源代码

JAVA打飞机游戏毕业设计 一、游戏概述 本游戏基于Java Swing开发&#xff0c;实现了经典的飞机射击游戏。玩家控制一架战斗机在屏幕底部移动&#xff0c;发射子弹击落敌机&#xff0c;同时躲避敌机攻击。游戏包含多个关卡&#xff0c;随着关卡提升&#xff0c;敌机速度和数量…

通俗易懂linux环境变量

如果想要清楚的了解环境变量&#xff0c;我觉得我们需要先大致搞清楚一个简单的事——什么是会话&#xff1f; 会话大致是什么&#xff1f; 在这里我们的目的是更好的理解环境变量&#xff0c;所以适当讲解一下会话即可。通常我们都是用xshell连接远程服务器&#xff0c;都会打…

【补题】Codeforces Round 715 (Div. 2) C. The Sports Festival

题意&#xff1a;给你一个序列&#xff0c;你可以对它重新排序&#xff0c;然后使每个i&#xff0c;max(a0,a1……ai)-min(a0,a1……ai)最小。问答案是多少 思路&#xff1a; C. The Sports Festival&#xff08;区间DP&#xff09;-CSDN博客 区间dp&#xff0c;完全没想到…

ubuntu系统文件误删(/lib/x86_64-linux-gnu/libc.so.6)修复方案 [成功解决]

报错信息&#xff1a;libc.so.6: cannot open shared object file: No such file or directory&#xff1a; #ls, ln, sudo...命令都不能用 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory重启后报错信息&…

SIFT算法详细原理与应用

SIFT算法详细原理与应用 1 SIFT算法由来 1.1 什么是 SIFT&#xff1f; SIFT&#xff0c;全称为 Scale-Invariant Feature Transform&#xff08;尺度不变特征变换&#xff09;&#xff0c;是一种用于图像特征检测和描述的经典算法。它通过提取图像中的局部关键点&#xff0c;…

NPOI操作EXCEL文件 ——CAD C# 二次开发

缺点:dll.版本容易加载错误。CAD加载插件时&#xff0c;没有加载所有类库。插件运行过程中用到某个类库&#xff0c;会从CAD的安装目录找&#xff0c;找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库&#xff0c;就用插件程序加载进…

Go字符串切片操作详解:str1[:index]

在Go语言中&#xff0c;return str1[:index] 是一个​​字符串切片操作​​&#xff0c;它截取字符串的一部分。让我们深入解析这个操作的含义和原理&#xff1a; 基本语法和含义 str1&#xff1a;原始字符串[:index]&#xff1a;切片操作符str1[:index]&#xff1a; ​​起始…

NVIDIA Dynamo:数据中心规模的分布式推理服务框架深度解析

NVIDIA Dynamo&#xff1a;数据中心规模的分布式推理服务框架深度解析 摘要 NVIDIA Dynamo是一个革命性的高吞吐量、低延迟推理框架&#xff0c;专为在多节点分布式环境中服务生成式AI和推理模型而设计。本文将深入分析Dynamo的架构设计、核心特性、代码实现以及实际应用示例&…

408第一季 - 数据结构 - 栈与队列的应用

括号匹配 用瞪眼法就可以知道的东西 栈在表达式求值运用 先简单看看就行&#xff0c;题目做了就理解了 AB是操作符,也是被狠狠加入后缀表达式了&#xff0c;然后后面就是*&#xff0c;只要优先级比栈顶运算符牛逼就放里面&#xff0c;很显然&#xff0c;*比牛逼 继续前进&#…

Ubuntu 下开机自动执行命令的方法

Ubuntu 下开机自动执行命令的方法&#xff08;使用 crontab&#xff09; 在日常使用 Ubuntu 或其他 Linux 系统时&#xff0c;我们常常需要让某些程序或脚本在系统启动后自动运行。例如&#xff1a;启动 Clash 代理、初始化服务、定时同步数据等。 本文将介绍一种简单且常用的…

jpackage 打包 jar包 为exe可执行程序

jpackage --input target/ --main-jar note.jar --runtime-image H:/Dpanbeifeng/apps/finalshell/jre --type app-image --dest output/ --main-class com.textmanager.Main --icon logo2.png --name 猫咪快笔记 jpackage 打包指令详细介绍 jpackage 概述 jpackage 是…

H5移动端性能优化策略(渲染优化+弱网优化+WebView优化)

一、渲染优化&#xff1a;首屏速度提升的核心​​ ​​1. 关键页面采用SSR或Native渲染​​ ​​适用场景​​&#xff1a;首页、列表页、详情页等强内容展示页面 ​​优化原理​​&#xff1a; ​​SSR&#xff08;服务端渲染&#xff09;​​&#xff1a;在服务端生成完整…

Matlab | matlab中的图像处理详解

MATLAB 图像处理详解 这里写目录标题图像处理 MATLAB 图像处理详解一、图像基础操作1. 图像读写与显示2. 图像信息获取3. 图像类型转换二、图像增强技术1. 对比度调整2. 去噪处理3. 锐化处理三、图像变换1. 几何变换2. 频域变换四、图像分割1. 阈值分割2. 边缘检测3. 区域分割五…

keysight是德科技N9923A网络分析仪

keysight是德科技N9923A网络分析仪 简  述&#xff1a;N9923A 是一款使用电池供电的便携式射频矢量网络分析仪&#xff0c;其中包括全 2 端口网络分析仪、电缆和天线测试仪、故障点距离测试仪、功率计以及 1 通道和 2 通道矢量电压表。 主要特性与技术指标 网络分析仪 * 2…

idea不识别lombok---实体类报没有getter方法

介绍 本篇文章&#xff0c;主要讲idea引入lombok后&#xff0c;在实体类中加注解Data&#xff0c;在项目启动的时候&#xff0c;编译不通过&#xff0c;报错xxx.java没有getXxxx&#xff08;&#xff09;方法。 原因有以下几种 1. idea没有开启lombok插件 2. 使用idea-2023…

本地主机部署开源企业云盘Seafile并实现外部访问

Seafile是一个开源、专业、可靠的云存储平台&#xff1b;解决文件集中存储、共享和跨平台访问等问题。这款软件功能强大&#xff0c;界面简洁、操作方便。 本文将详细的介绍如何利用本地主机部署 Seafile&#xff0c;并结合nat123&#xff0c;实现外网访问本地部署的 Seafile …

【从0-1的CSS】第1篇:CSS简介,选择器以及常用样式

文章目录 CSS简介CSS的语法规则选择器id选择器元素选择器类选择器选择器优先级 CSS注释 CSS常用设置样式颜色颜色名称(常用)RGB(常用)RGBA(常用)HEX(常用)HSLHSLA 背景background-colorbackground-imagebackground-size 字体text-aligntext-decorationtext-indentline-height 边…

SpringBoot+MySQL家政服务平台 设计开发

概述 基于SpringBootMySQL开发的家政服务平台完整项目&#xff0c;该系统实现了用户预约、服务管理、订单统计等核心功能&#xff0c;采用主流技术栈开发&#xff0c;代码规范且易于二次开发。 主要内容 系统功能架构 本系统采用前后端分离架构&#xff0c;前端提供用户交互…

3.1 HarmonyOS NEXT分布式数据管理实战:跨设备同步、端云协同与安全保护

HarmonyOS NEXT分布式数据管理实战&#xff1a;跨设备同步、端云协同与安全保护 在万物互联的时代&#xff0c;数据的跨设备流转与安全共享是全场景应用的核心需求。HarmonyOS NEXT通过分布式数据管理技术&#xff0c;实现了设备间数据的实时同步与端云协同&#xff0c;为开发…

高保真组件库:数字输入框

拖入一个文本框。 拖入一个矩形,作为整个数字输入框的边框,边框颜色为灰色DCDEE2,圆角半径为4。 拖入一个向上的箭头图标作为增加按钮,再拖入一个矩形,将向上箭头图标放入矩形内。矩形:18x15,边框颜色DCDEE2,边框左下可见,箭头图标:8x5,矩形置底,组合在一起命名”增…