多个Filter的执行顺序 | 职责链模式应用

news2024/12/17 19:36:42

文章目录

  • 前言
  • 一、多个Filter的执行顺序
    • 实操
      • 1. 配置web.xml方式注册Filter
        • 结论:
      • 2. 注解方式注册Filter
        • 结论:
  • 二、职责链模式的应用
    • 1. 回顾职责链模式
    • 2. Filter职责链模式的应用
  • 总结

前言

  Filter(过滤器) 是 Java Servlet 规范中定义的一种组件,用于在请求到达 Servlet 之前或响应返回给客户端之前对请求和响应进行处理。Filter 的主要作用是拦截、修改或处理传入的请求和传出的响应。

  tomcat作为web容器,提供了对 Filter 的支持。Tomcat 开启了Filter 的生命周期,当请求到达 Tomcat 时,Tomcat 将根据配置的 Filter 映射将请求传递给相应的 Filter。

  Filter 可以设置多个,并且按照一定顺序依次执行,这是因为使用了设计模式中的职责链模式。



一、多个Filter的执行顺序

  过滤器的执行顺序安装web.xml配置文件中的先后顺序排列。

实操

1. 配置web.xml方式注册Filter

  自定义过滤器:

public class FilterOne implements Filter{
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("过滤器1执行——————————————————————————————————————");
        chain.doFilter(request,response);
    }
}
public class FilterTwo implements Filter{
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("过滤器2执行——————————————————————————————————————");
        chain.doFilter(request,response);
    }
}
public class FilterThree implements Filter{
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("过滤器3执行——————————————————————————————————————");
        chain.doFilter(request,response);
    }
}

  配置 web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
         
  <!--注册SpringMVC的前端控制器——DispatcherServlet-->
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--关联配置文件-->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <!--启动级别1-->
    <load-on-startup>1</load-on-startup>
  </servlet>

  <!--/ 匹配所有请求,不包括jsp-->
  <!--/* 匹配所有请求,包括jsp-->
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  <!--配置过滤器FilterOne、FilterTwo、FilterThree-->
  <filter>
    <filter-name>FilterThree</filter-name>
    <filter-class>com.config.FilterThree</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>FilterThree</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <filter>
    <filter-name>FilterOne</filter-name>
    <filter-class>com.config.FilterOne</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>FilterOne</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <filter>
    <filter-name>FilterTwo</filter-name>
    <filter-class>com.config.FilterTwo</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>FilterTwo</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

结论:

  进入调试模式,可以看到过滤器统一放在一个容器中,顺序就是web.xml中从上到下的设置顺序。
在这里插入图片描述

  最后出来的打印执行顺序如下:按照解析web.xml的顺序添加的过滤器,并按照添加顺序执行的。
请添加图片描述



2. 注解方式注册Filter

  自定义过滤器:

@WebFilter(filterName = "FilterOne", urlPatterns = {"/*"})
public class FilterOne implements Filter{
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("过滤器1执行——————————————————————————————————————");
        chain.doFilter(request,response);
    }
}
@WebFilter(filterName = "FilterThree", urlPatterns = {"/*"})
public class FilterThree implements Filter{
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("过滤器3执行——————————————————————————————————————");
        chain.doFilter(request,response);
    }
}
@WebFilter(filterName = "FilterTwo", urlPatterns = {"/*"})
public class FilterTwo implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("过滤器2执行——————————————————————————————————————");
        chain.doFilter(request,response);
    }
}

结论:

  最后出来的打印执行顺序如下:
在这里插入图片描述


   根据类名的字母顺序排序,也就是说按字母顺序添加的过滤器,并且也按添加顺序执行的。
在这里插入图片描述



二、职责链模式的应用

1. 回顾职责链模式

  先来回顾职责链模式的特点:职责链模式——向上级申请加薪
  职责链模式特点如下:

  • 分离发送者和接收者:将发送者和接收者解耦,发送者只需要将请求发送给职责链的起始节点,而不需要知道具体的接收者。接收者也不需要知道请求的发送者是谁。

  • 多个处理节点处理请求:请求会在职责链上的多个处理节点中依次传递,每个节点都有机会处理请求。这样可以将复杂的处理逻辑分解成多个独立的节点。

  • 请求的处理可以终止:每个处理节点都可以决定是否继续传递请求给下一个节点或终止处理。这样可以灵活地控制请求的处理流程。

在这里插入图片描述

2. Filter职责链模式的应用

  所有过滤器都实现了doFilter方法,但是没有设置下级链的方法。
在这里插入图片描述
  Tomcat包中的ApplicationFilterFactory类中有个createFilterChain()方法,它的主要作用是将一组 Filters 以特定的顺序组合成一个 FilterChain,自动设置好了每一链的下级链。

  FilterChain 将被用于处理传入的请求,按照预定的顺序调用相应的 Filters 和最终的 Servlet(请求的方法)。
  例如:
在这里插入图片描述


  createFilterChain()方法大致的工作内容:

  1. 根据web.xml配置的 Filter 映射和顺序创建一个 FilterChain 对象。
  2. 将 FilterChain 初始化为包含所有配置的Filters,并按照预定的顺序进行排序。
  3. 返回创建的FilterChain 对象。


总结

  Filter 使用职责链模式(Chain of Responsibility Pattern)的优势:

  • 分离责任:将处理逻辑分散到多个 Filter 中,每个 Filter 只负责特定的处理任务。这样可以将复杂的处理逻辑分解为多个独立的模块,每个模块只关注自己的责任,实现了职责的分离。

  • 可扩展性:支持添加、移除和调整处理节点。可以根据需要增加新的 Filter,也可以移除或替换现有的 Filter,而不需要修改已有的代码。这使得系统具有良好的扩展性,可以灵活地应对变化的需求。

  • 可重用性:每个 Filter 负责独立的处理任务,可以被多个不同的请求或系统复用。这样可以避免重复编写相同的处理逻辑,提高代码的可重用性和可维护性。

  • 灵活性:允许根据实际需求动态调整处理流程。可以根据请求的类型、状态或其他条件来动态选择、排列和调整 Filter 的顺序,从而灵活地定制处理流程,以满足不同的业务需求。

  通过使用职责链模式,Filter 可以形成一个灵活、可扩展和可定制的处理链,每个 Filter 只负责特定的处理任务,处理逻辑分散到不同的节点中,实现了解耦合和职责的分离。这样可以提高代码的可维护性、可重用性和灵活性,同时使系统能够适应变化的需求。

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

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

相关文章

【计算机组成】三分钟了解顺序存储、直接存储、随机存储和相联存储的区别

一.按地址访问和按内容访问的区别 按地址访问&#xff08;顺序存储、直接存储和随机存储&#xff09;&#xff1a;我知道这个数据存在哪个地址中&#xff0c;现在我把这个地址给你&#xff0c;麻烦你帮我找出我要的数据来 按内容访问&#xff08;相联存储&#xff09;&#xff…

Netty编解码机制(一)

1.编码和解码基本介绍 1>.编写网络应用程序时,因为数据在网络中传输的都是二进制字节码数据,在发送数据时就需要编码,接收数据时就需要解码; 2>.codec(编解码器)的组成部分有两个: decoder(解码器)和 encoder(编码器).encoder(编码器)负责把业务数据转换成字节码数据,而…

BurpSuite—-Scanner模块(漏洞扫描)

本文主要BurpSuite—-Scanner模块(漏洞扫描)介绍的相关内容 关于BurpSuite的安装可以看一下之前这篇文章&#xff1a; http://t.csdn.cn/cavWt 一、简介 Burp Scanner 是一个进行自动发现 web 应用程序的安全漏洞的工具。它是为渗透测试人员设计的&#xff0c;并且它和你现有…

Revit幕墙:这些命令在幕墙嵌板中的妙用及快速幕墙

一、Revit中这些命令在幕墙嵌板中的妙用 在我们做幕墙时&#xff0c;通常会有不同种类的幕墙&#xff0c;比如材质不同&#xff0c;颜色不同。这时我们就需要去选中嵌板进行替换新样式的嵌板。 1.通常我们在替换嵌板时都是通过Tab切换&#xff0c;然后选中嵌板。这样进行来回切…

windows免费版切割pdf拆分pdf提取pdf指定页码小工具

如图所示&#xff1a;选择pdf文件&#xff0c;输入指定页码区间&#xff0c;使用逗号分隔&#xff0c;逗号不区分中英文。如输入1-10&#xff0c;11-20&#xff0c;21-21&#xff0c;点击开始分割&#xff0c;会拆分出1-10.pdf&#xff0c;11-20.pdf&#xff0c;21-21.pdf&…

短视频矩阵源码-智能剪辑生成技术数值组如何编程?

短视频混剪生成时长逻辑一般采用根据用户设定的总时长、视频数量、时长比例等参数计算出每个视频在混剪中所占的时长&#xff0c;然后根据视频的总时长与所占比例来划分每个视频在混剪中的时长&#xff0c;最后将各个视频拼接起来形成混剪视频。此算法可以进行灵活的时长调整和…

rt下降40%?程序并行优化六步法 | 京东云技术团队

1 背景 性能优化是我们日常工作中很重要的一部分&#xff0c;主要有以下原因&#xff1a; 降低服务器和带宽等硬件成本&#xff1a;用更少的资源处理更多的请求提高现实世界的运行效率&#xff1a;人机处理效率存在数量级的偏差&#xff0c;同样机器世界的效率提升能带来现实…

十一、配置内网穿透实现消息模块和授权登陆模块

开通内网穿透的服务&#xff08;后端8333&#xff0c;前端8080&#xff09;&#xff1a; 启动内网穿透服务&#xff1a; 创建CourseApiController来实现关键词查询课程信息&#xff1a; package com.lxl.ggkt.vod.api;import com.baomidou.mybatisplus.core.conditions.query.…

2023年认证杯SPSSPRO杯数学建模D题(第一阶段)立体车库的自动调度问题全过程文档及程序

2023年认证杯SPSSPRO杯数学建模 D题 立体车库的自动调度问题 原题再现&#xff1a; 随着人们生活水平的提高&#xff0c;汽车保有量日益增加&#xff0c;而城市土地资源有限&#xff0c;传统平面停车场土地面积利用率低, 这样便形成了交通拥挤、停车困难的现象。为解决该问题…

资深测试老鸟整理,超全自动化测试用例详解-小技巧总结...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 Python自动化测试&…

PCA的数学原理和python实现

最近学习了一下PCA&#xff0c;具体原理网址如下&#xff1a; CodingLabs - PCA的数学原理 主要原理是通过线性变换将原始数据变换为一组各维度线性无关的表示&#xff0c;其中将方差最大的方向作为主要特征。提取数据的主要特征分量&#xff0c;可用于高维数据的降维 主要算…

工作3年裸辞,从18K到38K,面试也····

现在的面试好像也不是那么的难 工作3年&#xff0c;换了好几份工作&#xff08;行业流行性大&#xff09;&#xff0c;每次工作都是裸辞。朋友都觉得不可思议。因为我一直对自己很有信心&#xff0c;而且特别不喜欢请假面试&#xff0c;对自己负责也对公司负责。 但是这次没想…

Axure 教程:动态分组条形图(中继器)

本文将教大家如何用AXURE中的中继器动态分组条形图 一、效果介绍 如图&#xff1a; 预览地址&#xff1a;https://v7cmdp.axshare.com 下载地址&#xff1a;https://download.csdn.net/download/weixin_43516258/87807121?spm1001.2014.3001.5503 二、功能介绍 简单填写中继…

Lucene(4):Field域类型

1 Field属性 Field是文档中的域&#xff0c;包括Field名和Field值两部分&#xff0c;一个文档可以包括多个Field&#xff0c;Document只是Field的一个承载体&#xff0c;Field值即为要索引的内容&#xff0c;也是要搜索的内容。 是否分词(tokenized) 是&#xff1a;作分词处理…

requests爬虫

目录 一、爬虫概念及分类 二、requests模块 1、网页地址内容获取 2、图片爬取 3、UA伪装 三、动态加载数据 一、爬虫概念及分类 爬虫: 通过编写代码&#xff0c;让其模拟浏览器上网&#xff0c;然后在互联网中抓取数据的过程 分类&#xff1a;1、通用爬虫&#xff1a;要…

Linux: ARM32各CPU模式下栈配置

文章目录 1. 前言2. 背景3. ARM32 中断向量表 和 中断处理流程3.1 ARM32 中断向量表3.2 ARM32 中断处理流程 4. ARM32 各CPU模式下的栈配置4.1 SVC模式下各CPU栈配置(内核栈配置)4.1.1 BOOT CPU SVC模式栈配置(内核栈配置)4.1.2 非 BOOT CPU SVC模式栈配置(内核栈配置) 4.2 中断…

实现快速多点触控,让App自动化测试操作更方便

目录 前言&#xff1a; PyAutoGUI简介&#xff1a; 代码示例&#xff1a; 总结&#xff1a; 前言&#xff1a; 随着智能设备的普及&#xff0c;触摸点的数量和触摸操作的复杂度也在不断增加。要想在触控界面上获得更高效率和更好的体验&#xff0c;多点触控操作是必不可少的…

历经70+场面试,我发现了大厂面试的套路都是···

今年的金三银四刚刚过去&#xff0c;我又想起了我在去年春招时面试了50余家&#xff0c;加上暑期实习面试了20余家&#xff0c;加起来也面试了70余场的面试场景了。 基本把国内有名的互联网公司都面了一遍&#xff0c;不敢说自己的面试经验很丰富&#xff0c;但也是不差的。 …

【JAVAEE】认识网络及网络通信

目录 1.网络发展史 1.1独立模式 1.2网络互连 1.2.1局域网 1.2.2广域网 2.网络通信基础 2.1IP地址 2.2端口号 2.3协议 2.4五元组 2.5协议分层 2.5.1什么是协议分层 2.5.2协议分层的作用 2.5.3TCP/IP五层&#xff08;或四层&#xff09;模型 3.封装和分用 1.网络发…

调用百度API自动生成春联

目录 1、作者介绍2、百度智能春联介绍录2.1 功能介绍2.2 技术特色 3、智能春联API接口介绍3.1 请求参数3.2 返回参数 4. 操作流程5. 代码实现 1、作者介绍 范宇帅&#xff0c;男&#xff0c;西安工程大学电子信息学院&#xff0c;2022级研究生 研究方向&#xff1a;多机器人协…