【Springboot】Filter 过滤器的使用

news2024/11/24 21:04:14

一、基本介绍

        过滤器 Filter 作为 Java 三大器之一,在 Java Web 的使用中有很高的地位。所谓过滤器,就是实现了 javax.servlet.Filter 接口的服务器端程序,就是对事物进行过滤的。在 Web 中的过滤器,当然就是对请求进行过滤,我们使用过滤器,就可以对请求进行拦截,然后做相应的处理,实现许多特殊功能。如登录控制,权限管理,过滤敏感词汇等。

        使用Filter完整的流程是:Filter对用户请求进行预处理,接着将请求交给Servlet进行预处理并生成响应,最后Filter再对服务器响应进行后处理。

二、过滤器原理

        当我们使用过滤器时,过滤器会对游览器的请求进行过滤,过滤器可以动态的分为 3 个部分,1. 放行之前的代码,2. 放行,3. 放行后的代码,这 3 个部分分别会发挥不同作用。

  • 第一部分代码会对游览器请求进行第一次过滤,在 HttpServletRequest 到达 Servlet 之前,拦截客户的 HttpServletRequest。
  • 第二部分根据需要检查 HttpServletRequest,也可以修改 HttpServletRequest 头和数据,如果还有过滤器,那么就继续交给下一个过滤器。

  • 第三部分在 HttpServletRequest 到达客户端之前,拦截 HttpServletResponse,对返回的 Web 资源再次进行过滤处理。

我们使用过滤器,也就是说,不止请求会经过过滤器,我们的响应也会经过过滤器。

三、过滤器的作用

 * Examples that have been identified for this design are
 * 1) Authentication Filters, 即用户访问权限过滤
 * 2) Logging and Auditing Filters, 日志过滤,可以记录特殊用户的特殊请求的记录等
 * 3) Image conversion Filters,图像转换过滤器
 * 4) Data compression Filters ,数据转换
 * 5) Encryption Filters ,安全加密
 * 6) Tokenizing Filters ,词法分析
 * 7) Filters that trigger resource access events ,资源访问事件触发过滤器
 * 8) XSL/T filters 
 * 9) Mime-type chain Filter ,文件类型链过滤器

四、过滤器(Filter)接口

        我们学习过滤器,肯定就要先看一下官方给我们提供的过滤器接口。下面我们使用 Idea 来查看 Filter。

Filter 有如下几个方法:

  • void init(FilterConfig filterConfig) 用于完成过滤器的初始化。
  • doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) 实现过滤功能,将该方法对每个请求增加额外的处理。

  • void destroy() 用于过滤器销毁前,完成某些资源的回收。

五、使用过滤器(Filter)

先自定义 FirstFilter 类实现 Filter 接口:

public class FirstFilter implements Filter {

    @Override 
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig); 
        System.out.println("--------FirstFilter 初始化完成-------"); 
    }

    @Override 
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,                         FilterChain filterChain) throws IOException, ServletException {
        System.out.println("------对 First request 进行过滤 --------");
        //下面这行代码就是放行    
        filterChain.doFilter(servletRequest, servletResponse); 
        System.out.println("------对 First response 进行过滤 --------");
    }

    @Override public void destroy() {
        Filter.super.destroy(); 
        System.out.println("firstFilter 已销毁"); 
    }

}

再自定义 SecondFilter 类实现 Filter 接口:

public class SecondFilter implements Filter {

    @Override 
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig); 
        System.out.println("--------SecondFilter 初始化完成-------"); 
    }

    @Override 
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,                         FilterChain filterChain) throws IOException, ServletException {
        System.out.println("------对 Second request 进行过滤 --------");
        //下面这行代码就是放行
        filterChain.doFilter(servletRequest, servletResponse); 
        System.out.println("------对 Second response 进行过滤 --------");
    }

    @Override public void destroy() {
        Filter.super.destroy(); 
        System.out.println("SecondFilter 已销毁"); 
    }

}

再修改 WebConfig 配置类:

@Configuration
public class WebConfig {

    @Bean 
    public FilterRegistrationBean firstFilterRegistrationBean() {
        FilterRegistrationBean<Filter> filterFilterRegistrationBean = new FilterRegistrationBean<>(); 
        // 对哪些路径进行过滤
        filterFilterRegistrationBean.addUrlPatterns("/*");              
        filterFilterRegistrationBean.setOrder(1); // 设置优先级 ,数字越小,优先级越高
        FirstFilter filter = new FirstFilter(); // 绑定过滤器 
        filterFilterRegistrationBean.setFilter(filter); 
        return filterFilterRegistrationBean; 
    }

    @Bean 
    public FilterRegistrationBean secondFilterRegistrationBean() {
        FilterRegistrationBean<Filter> filterFilterRegistrationBean = new FilterRegistrationBean<>();
        filterFilterRegistrationBean.addUrlPatterns("/hello");         
        filterFilterRegistrationBean.setOrder(2);  // 设置优先级
        // 绑定过滤器
        SecondFilter filter = new SecondFilter(); 
        filterFilterRegistrationBean.setFilter(filter); 
        return filterFilterRegistrationBean; 
    }

}

启动服务器,然后我们在浏览器中随便输入一个 url 地址进行访问:

浏览器输出: 

控制台输出:

------对 request 进行过滤 ---------
------对 response 进行过滤 --------

现在,我们就已经可以得出两个结论了,过滤器并不会管资源是否存在,而只会对配置的拦截路径进行拦截。拦截不仅会对请求进行拦截,而且还会对相应进行拦截。

六、多个 Filter 的执行顺序

 上面我们配置了 2 个过滤器,那么我们怎么知道那个过滤器先执行呢?

启动服务器,然后我们浏览器输入 http://localhost:8080/hello 来进行访问,查看控制台输出

------对 First request 进行过滤 --------
------对 Second request 进行过滤 --------
------对 Second response 进行过滤 --------
------对 First response 进行过滤 --------

我们可以看见 FirstFilter 先进行过滤,然后交给 SecondFilter ,然后访问资源,然后 SecondFilter 对响应进行过滤,然后 FirstFilter 对响应进行过滤。图示如下:  

七、过滤器(Filter)生命周期

Filter 有三个阶段,分别是初始化,拦截和过滤,销毁。

  • 初始化阶段:web 应用程序启动时,web 服务器将创建 Filter 的实例对象,并调用其 init 方法,完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作,filter 对象只会创建一次,init 方法也只会执行一次。通过 init 方法的参数,可获得代表当前 filter 配置信息的 FilterConfig 对象(永远只调用一次)
  • 拦截和过滤阶段:只要请求资源的路径和拦截的路径相同,那么过滤器就会对请求进行过滤,这个阶段在服务器运行过程中会一直循环,不管第几次,都在调用doGet(),doPost() 方法之前。
  • 销毁阶段:当服务器(Tomcat)关闭时,Web 容器调用 destroy 方法销毁 Filter。destroy 方法在 Filter 的生命周期中仅执行一次。在 destroy 方法中,可以释放过滤器使用的资源(永远只调用一次);

八、FilterConfig 和 FilterChain 说明

        FilterConfig 和 FilterChain 这2个对象是由服务器 (Tomcat) 在创建和调用 Filter 对象时所传入的,这2个对象十分有用,FilterConfig 对象可以读取我们配置的初始参数,FilterChain 可以实现多个 Filter 之间的连接。

1、FilterConfig 

先看一下源码:

public interface FilterConfig {
    String getFilterName();

    ServletContext getServletContext();

    String getInitParameter(String var1);

    Enumeration<String> getInitParameterNames();
}

里面的方法就 4 个,下面我们分别进行讲解

  • getFilterName():获取 filter 的名称
  • getServletContext():获取 ServletContext
  • getInitparamter(String var1):获取配置的初始参数的值
  • getInitParamterNames():获取配置的所有参数名称

2、FilterChain

先看一下源码

public interface FilterChain {
    void doFilter(ServletRequest var1, ServletResponse var2) throws IOException, ServletException;
}

我们查看源码,可以发现 FilterChain 就只有一个方法,其实这个方法就是用来对拦截进行放行的,如果有多个拦截器,那么就会继续调用下一个 Filter 进行拦截。doFilter 方法需要传入个参数,一个是 ServletRequest,一个是 ServletResponse 参数,这个直接传入进行。

Tomcat 在调用过滤器时,默认就会传入 Request 和 Response,这个参数封装了请求和响应,我们直接使用就行。ServletResquest 和 ServletResponse 可以直接强转成 HttpServletRequest 和 HttpServletResponse,然后使用相应的方法。

将 ServletRequest 转成 HttpServletRequest

    @Override 
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,                         FilterChain filterChain) throws IOException, ServletException {
       
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        
    }

九、参考文档

JavaWeb 过滤器 (Filter) 详解

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

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

相关文章

2023常见自动化测试工具集合

1、Appium -------> AppUI自动化测试 官网&#xff1a;http://appium.io Appium 是一个移动端自动化测试开源工具&#xff0c;支持iOS 和Android 平台&#xff0c;支持Python、Java 等语言&#xff0c;即同一套Java 或Python 脚本可以同时运行在iOS 和Android平台&#x…

关于图像分割SDK的一些基础认识

随着科技的不断发展&#xff0c;图像分割SDK已经成为了一个备受关注的话题。而在众多图像分割SDK中&#xff0c;美摄图像分割SDK以其独特的功能和优势脱颖而出。本文将从美摄图像分割SDK的企业价值和互联网娱乐方面&#xff0c;介绍其宣传文章的具体写作规范。 在企业价值方面&…

如何用IP地址解决广告精准投放问题

IP地址可以在广告精准投放中发挥关键作用&#xff0c;因为它提供了有关用户的地理位置信息。通过结合IP地址和其他数据&#xff0c;广告公司和平台可以更精准地定位广告受众&#xff0c;从而提高广告投放的效果。以下是一些方式&#xff0c;说明了如何使用IP地址来解决广告精准…

BCT(block change tracking)引起的异机恢复问题

前提说明 exadata 12.1.0.2的环境&#xff0c;做异机恢复&#xff0c;恢复到单机环境。 现象及报错 Rman异机恢复hang住不动&#xff08;已做set newname&#xff09;&#xff0c;db的alert日志中出现以下报错 --个人印象中还有asmb的trc报错&#xff0c;这次没有找到 原因及解…

限流与下载接口请求数控制

收银台系统相对于互联网应用流量要平稳很多&#xff0c;高峰流量也就平时的三倍&#xff0c;完全是可控的&#xff0c;我们这里用限流主要是控制后台同时下载XLS表格的请求数&#xff0c;因为后台系统要提供大量的导出XLS表格功能&#xff0c;收银员与管理人员需要用我们导出的…

标准化格式输出:DateTimeFormatter

public static void main(String[] args) {LocalDateTime ldt LocalDateTime.now();System.out.println(ldt);//格式化输出时间//创建DateTimeFormatter对象来进行格式化DateTimeFormatter dateTimeFormatter DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒&…

聊天室即时通讯系统源码 类似微信的H5聊天系统APP源码 ThinkPHP内核

前端&#xff1a; 用Dcloud 的 uni-app全系,基于vue.js和微信小程序开发模式。 目前支持APP&#xff08;android、ios&#xff09;、H5、微信小程序、支付宝小程序5端。 在特定场景可以用weex进行原生渲染。 APP用的是Dcloud 公司的H5进行原生接口调用。 后端&#xff1a;…

图像语义分割 pytorch复现U2Net图像分割网络详解

图像语义分割 pytorch复现U2Net图像分割网络详解 1、U2Net网络模型结构2、block模块结构解析RSU-7模块RSU-4Fsaliency map fusion module U2Net网络结构详细参数配置RSU模块代码实现RSU4F模块代码实现u2net_full与u2net_lite模型配置函数U2Net网络整体定义类损失函数计算评价指…

LXC、Docker、 Kubernetes 容器以及Hypervisor的区别

LXC、Docker、 Kubernetes 容器以及Hypervisor的区别 SaaS: Software-as-a-Service&#xff08;软件即服务&#xff09; PaaS: Platform-as-a-Service&#xff08;平台即服务&#xff09; IaaS: Infrastructure-as-a-Service&#xff08;基础设施即服务&#xff09; 1、Docke…

划重点!3DEXPERIENCE SOLIDWORKS 2024 十大增强功能

SOLIDWORKS 2024 以更加强大的姿态亮相&#xff0c;帮助您重塑设计。为了助力您简化和加快由概念到成品的产品开发流程&#xff0c;SOLIDWORKS 2024 涵盖全新以用户为中心的增强功能&#xff0c;致力帮您实现更智能、更快速地与您的团队和外部合作伙伴协同工作。本篇为大家介绍…

微信公众号怎么从个人转为企业?

公众号账号迁移的作用是什么&#xff1f;只能变更主体吗&#xff1f;1.可合并多个公众号的粉丝、文章&#xff0c;打造超级大V2.可变更公众号主体&#xff0c;更改公众号名称&#xff0c;变更公众号类型——订阅号、服务号随意切换3.可以增加留言功能4.个人订阅号可迁移到企业名…

封箱机不打盖是什么原因?

折盖封箱机是封箱机中自动化程度比较高的一款设备&#xff0c;该机既可以单机使用&#xff0c;也可以配自动化流水线一起使用&#xff0c;实现无人化操作&#xff0c;但这款设备在使用的过程中有时会出现一些小问题&#xff0c;今天就其中的一个常见故障-----不打盖的问题和您做…

单片机TDL的功能、应用与技术特点 | 百能云芯

在现代电子领域中&#xff0c;单片机&#xff08;Microcontroller&#xff09;是一种至关重要的电子元件&#xff0c;广泛应用于各种应用中。TDL&#xff08;Time Division Multiplexing&#xff0c;时分多路复用&#xff09;是一种数据传输技术&#xff0c;结合单片机的应用&a…

MySQL InnoDB引擎深入学习的一天(InnoDB架构 + 事务底层原理 + MVCC)

目录 逻辑存储引擎 架构 概述 内存架构 Buffer Pool Change Buffe Adaptive Hash Index Log Buffer 磁盘结构 System Tablespace File-Per-Table Tablespaces General Tablespaces Undo Tablespaces Temporary Tablespaces Doublewrite Buffer Files Redo Log 后台线程 事务原…

关于脑部的基础知识

脑部的基础知识 1 解剖学基本术语&#xff1a;1.1 解剖学方向1.2 解剖学平面1.3 神经元集合体1.4 神经元轴突集合体 2 中枢神经系统CNS2.1 脑 Brain2.1.1 **大脑** 大脑皮层 皮层下结构2.1.2 **间脑** **丘脑 下丘脑 垂体**2.1.3 **中脑 ** **顶盖 ** **大脑脚**2.1.4 脑桥…

【算法|前缀和系列No.2】牛客网 DP35 【模板】二维前缀和

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【牛客网刷题】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&#xff0c;希…

功能测试-本地缓存修改时间戳:操作支付中心页面触发二次挽留弹窗

需求&#xff1a;在活动期间&#xff0c;指定的用户在关闭支付中心个人会员页时&#xff0c;增加二次挽留弹窗机制 涉及端口&#xff1a;PC官网支付中心、移动端官网支付中心、插件端支付中心 触发频率&#xff1a;用户每天触发一次&#xff08;需求写的其实这是错误的&#…

实赣!赣州与开源网安联手打造软件供应链安全检测中心

10月16日&#xff0c;开源网安与赣州市行政审批局、赣州市网信办三方先后签署战略协议及投资协议&#xff0c;签约后将在赣州打造软件供应链安全检测中心&#xff0c;为数字政府、数字经济等领域提供全面安全检测和软件安全运营监测等服务&#xff0c;提升软件的安全与质量&…

【IEEE会议】第三届信息技术与当代体育国际学术会议(TCS 2023)

【IEEE】第三届信息技术与当代体育国际学术会议&#xff08;TCS 2023&#xff09; 2023 3rd International Conference on Information Technology and Contemporary Sports 2023年第三届信息技术与当代体育国际学术会议&#xff08;TCS 2023&#xff09;将于2023年12月22-24…

阿里云服务器ECS实例规格族c/g/r等字母说明

阿里云服务器ECS实例命名规则&#xff1a;ecs.<规格族>.large字母含义命名说明&#xff0c;包括x86、ARM架构、GPU异构计算、弹性裸金属、超级计算集群SCC云服务器&#xff0c;c代表计算型、g代表通用型、r代表内存型、u代表通用算力型、e代表经济型e实例&#xff0c;阿里…