【Springboot】Filter 过滤器的使用

一、基本介绍

        过滤器 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.mzph.cn/news/107043.shtml

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

相关文章

解决axios不发起请求的问题

一个很简单axios发起的get请求&#xff0c;但是network就是没有xhr记录&#xff1a; 找了半天也没有找到原因&#xff0c;后来问了chatgpt才找到原因&#xff1a; 请求地址url前面没有const关键字&#xff0c;此时url相当于undefined&#xff0c;而axios在url为undefined时不会…

天猫商品品牌数据采集接口,天猫商品详情数据接口,天猫API接口

天猫商品品牌数据采集方法如下&#xff1a; 打开天猫&#xff0c;进入任意一个品牌的商品页面。点击浏览器右上角的“选项”按钮&#xff0c;选择“检查元素”或使用快捷键CtrlShiftI&#xff08;Windows&#xff09;或CmdOptionI&#xff08;Mac&#xff09;打开开发者工具。…

JVM类装载器详解

目录 一、类装载的过程 1.1 装载(Load) 1.2 链接(Link) 1.2.1 验证(Varify) 二、类装载器组成 1. JVM 中内置了三个重要的 ClassLoader&#xff0c;同时按如下顺序进行加载&#xff1a; 2、图解 3、加载原则 所谓的双亲委派 类加载器负责在运行时将Java类动态加载到Java虚拟机&…

多关键词高亮显示

引入关键词文件&#xff0c;符合有条件的背景色高亮显示&#xff0c;也可取消。 <div id"testHtml"><p>写入的文本</p><p>关键词</p></div> var str 多个关键词&#xff0c;关键词文件&#xff0c;关键词 var strL str.replac…

nginx报错

故障1&#xff1a;nginx 502错误 故障描述 一个 post 的请求&#xff0c;直接调接口服务数据正常返回&#xff0c;但是通过 nginx 代理后&#xff0c; 什么都没有返回 nginx错误日志 upstream sent invalid chunked response while reading upstream 原因 http协议版本不一致…

【C++】C++11—— 包装器

​ ​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;C学习 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 上一篇博客&#xff1a;【C】C11…

2023年中国TFT-LCD面板产业链、需求量及市场规模分析[图]

按显示技术尺寸来分&#xff0c;主要分为大尺寸和小尺寸&#xff08;10寸以下&#xff09;&#xff0c;TFT-LCD行业下游主要是各类型消费电子&#xff0c;包括PC显示器&#xff0c;液晶电视&#xff0c;智能手机等。 TFT&#xff0d;LCD面板产业链 资料来源&#xff1a;共研产…

【广州华锐互动】利用VR开展细胞基础实验教学有什么好处?

在科技发展的驱动下&#xff0c;虚拟现实&#xff08;VR&#xff09;技术已被广泛应用于各个领域&#xff0c;包括教育和医学。尤其是在医学教育中&#xff0c;VR技术已成为一种革新传统教学模式的有效工具。本文将探讨使用VR进行细胞基础实验教学的优势。 首先&#xff0c;VR技…

(SCADA)监控与数据采集系统

SCADA应用于监控和采集数据来控制工业过程软件。它通过收集和传输实时数据&#xff0c;帮助操作员监视和控制各种设备和过程。这篇文章将介绍SCADA系统的工作原理、应用行业和场景&#xff0c;以及所需的模块和硬件设备。最后&#xff0c;还会详细介绍几款国外SCADA软件给大家参…

VUE整合Echarts实现简单的数据可视化

文章目录 前言 一、Echarts的安装 二、可视化渲染 1.柱状图 2.饼图 3.主题的下载 总结 前言 ECharts是一款功能强大的前端数据可视化库&#xff0c;支持多种图表类型和统计图表、地理数据可视化、关系型数据展示、多维数据处理和商业智能功能。通过广泛的图表类型、统计分析…

FPGA面试题(5)

一.FPGA可以综合实现为RAM/ROM/CAM的三种资源及注意事项 三种资源&#xff1a;BLOCK RAM&#xff0c;触发器&#xff08;FF&#xff09;&#xff0c;查找表&#xff08;LUT&#xff09; 注意事项&#xff1a; 1.生成RAM&#xff0c;首选BLOCK RAM。因为BLOCK RAM是已经存在的“…

Springboot项目中加载Groovy脚本并调用其内部方代码实现

前言 项目中部署到多个煤矿的上&#xff0c;每一种煤矿的情况都相同&#xff0c;涉及到支架的算法得写好几套&#xff0c;于是想到用脚本实现差异变化多的算法&#xff01;一开始想到用java调用js脚本去实现&#xff0c;因为这个不需要引入格外的包&#xff0c;js对我来说也没…

测试需要写测试用例吗?

如何理解软件的质量 我们都知道&#xff0c;一个软件从无到有要经过需求设计、编码实现、测试验证、部署发布这四个主要环节。 需求来源于用户反馈、市场调研或者商业判断。意指在市场行为中&#xff0c;部分人群存在某些诉求或痛点&#xff0c;只要想办法满足这些人群的诉求…

docker部署多个node-red操作过程

docker部署多个node-red操作过程 一、docker安装教程二、docker安装node-red2.1 拉取镜像2.2 创建目录并分配权限 三、 docker操作node-red3.1 部署node-red3.2 查看\关闭\删除容器 四、Docker删除Redis镜像 回到目录 一、docker安装教程 【docker使用安装教程】 回到目录 …

NI GPIB-140A 使用缓冲传输技术 边缘人工智能

NI GPIB-140A 使用缓冲传输技术 边缘人工智能 GPIB总线扩展器—GPI b-140 a可以将GPIB系统的电缆长度延长一千米&#xff0c;而不会影响GPIB的完整性&#xff0c;也不需要修改软件。该配件使用缓冲传输技术&#xff0c;以高达1.1 Mb/s (IEEE 488.1)或2.8 Mb/s (HS488)的速率传…

安科瑞预付费系统在某大型连锁农贸市场的设计应用

安科瑞 崔丽洁 摘要 本远程预付费管理系统采用智能远程预付费电表&#xff08;DTSY1352-NK/DDSY1352-NK系列&#xff09;&#xff0c;NB智能远传水表&#xff0c;采集各商户实时用电量、用电量总数&#xff0c;通过平台定时结算&#xff0c;结算账户余额&#xff0c;从而进行智…

4d动感影院座椅5d动感影院体验馆大型7D互动影院

今天来讲一下市场上现在受欢迎的5d7d影院&#xff0c;组成部分&#xff0c;落地方案 5D影院的系统组成部分&#xff1a;1、动感座椅、2、投影幕(银幕)和投影机、3、音箱、4、各种的动感特效、5、5d影院眼镜&#xff0c;很简单的组成硬件&#xff0c;就可以组成一套的5d影院设备…

专题三:穷举、暴搜、深搜、回溯、剪枝【递归、搜索、回溯】

1、全排列 class Solution { public:vector<vector<int>> ret;vector<int> path;bool check[7];void dfs(vector<int>& nums){if(nums.size() path.size()) {ret.push_back(path);return;}for(int i 0;i < nums.size();i){if(check[i] fals…

HBase基础

HBase基础 参考 https://www.bilibili.com/video/BV1bC4y1b7Q1 HBase 简介 定义 HBase是一种分布式、可扩展、支持海量数据存储的NoSQL数据库(k-v)。 数据量越大&#xff0c;优势越明显&#xff1b;数据量小&#xff0c;比较消耗内存&#xff0c;耗资源&#xff1b;数据量大…

如何优雅的实现接口统一调用

耦合问题 有些时候我们在进行接口调用的时候&#xff0c;比如说一个push推送接口&#xff0c;有可能会涉及到不同渠道的推送&#xff0c;以我目前业务场景为例&#xff0c;我做结算后端服务的&#xff0c;会与金蝶财务系统进行交互&#xff0c;那么我结算后端会涉及到多个结算…