惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
博客园_首页
H
Hackread – Cybersecurity News, Data Breaches, AI and More
T
ThreatConnect
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 聂微东
H
Help Net Security
T
Threat Research - Cisco Blogs
Blog — PlanetScale
Blog — PlanetScale
A
Arctic Wolf
G
Google Developers Blog
量子位
U
Unit 42
I
InfoQ
V
V2EX
F
Fox-IT International blog
P
Privacy & Cybersecurity Law Blog
V
Visual Studio Blog
J
Java Code Geeks
大猫的无限游戏
大猫的无限游戏
C
CERT Recently Published Vulnerability Notes
博客园 - 三生石上(FineUI控件)
T
The Exploit Database - CXSecurity.com
T
Tailwind CSS Blog
SecWiki News
SecWiki News
Know Your Adversary
Know Your Adversary
MyScale Blog
MyScale Blog
宝玉的分享
宝玉的分享
The Hacker News
The Hacker News
Project Zero
Project Zero
Application and Cybersecurity Blog
Application and Cybersecurity Blog
月光博客
月光博客
Recent Commits to openclaw:main
Recent Commits to openclaw:main
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
G
GRAHAM CLULEY
C
Cisco Blogs
I
Intezer
Simon Willison's Weblog
Simon Willison's Weblog
O
OpenAI News
Recorded Future
Recorded Future
T
Tenable Blog
W
WeLiveSecurity
腾讯CDC
Stack Overflow Blog
Stack Overflow Blog
T
The Blog of Author Tim Ferriss
www.infosecurity-magazine.com
www.infosecurity-magazine.com
D
Docker
C
Cybersecurity and Infrastructure Security Agency CISA
PCI Perspectives
PCI Perspectives

技术改变视野

为程序员、设计师打造的摸鱼社区:摸鱼派! - 技术改变视野 我在 GitHub 上的开源项目 - 技术改变视野 为IDEA/Git配置GPG密钥,点亮GitHub Verified Commit标识 - 技术改变视野 从 SpringMVC 转为使用 SpringBoot —— 手把手带你使用 Intellij IDEA 最快速地搭建 SpringBoot+MyBatis(无 XML)+Thymeleaf - 技术改变视野 无题 - 技术改变视野 年轻人的第一辆京牌电动车 - 技术改变视野 我们忙碌且漫长的一生,有多久是为自己而活? 说说《后浪》 - 技术改变视野 离线使用 Google Fonts:让你的网站更精致 | goofoffline 神器,一键下载生成离线字体库! - 技术改变视野 🎨 适用于 Solo / Bolo 的清新高级主题 —— Sakura | 移植自 WordPress 主题 - 技术改变视野 大白话之Java级联调用:一个类,一条语句,同时调用好几个方法,串成一串 - 技术改变视野 大白话 | Java初学指♂男:“说说初学的误区与死结”( 壹 | 反射与Field ) - 技术改变视野 一个实例理解Java的接口(interface)用处与用法 一个实例带你理解JavaBean 实例带你搞懂Java多线程&&线程池之(壹):线程池与多线程的关系和区别 实例带你搞懂Java多线程&&线程池之(贰):简单的线程池应用 - 技术改变视野 实例带你获取多线程Thread的返回值之 (壹) - Callable的运行 实例带你学会简单的Java Thread多线程 - 技术改变视野 实例带你获取多线程Thread的返回值之 (贰) - Callable配合线程池返回数据 一个实例理解Java Runnable多线程用处与用法 一个最简单的实例理解Semaphore在Java中的作用 从零开始OpenSSL之 (壹) - 使用genrsa、rsa、rsautl生成公私钥 从零开始 OpenSSL 之 (贰) - 使用 rsautl 解密文件 大白话之Docker(壹):快速入门&&简单官方实例 大白话之耦合性:什么是耦合性和内聚性?用编程语言实例讲解! - 技术改变视野 大白话之Docker(贰):简单部署一个Tomcat服务并发布内容 - 技术改变视野 大白话之从零讲解DVWA(壹)-SQL注入(SQL Injection) Low Level - 技术改变视野 大白话之从零讲解DVWA(贰)-SQL注入(SQL Injection) Medium/High Level Java日志插件-Slog4J下载 大白话之必会Java Atomic | 线程一点也不安全(一):比自增和synchronized更快速、靠谱的原子操作(调用C语言) Log-MySQL root用户登录后无法查看数据库全部表/正常访问数据库 Access denied for user 'root'@'localhost' to database - 技术改变视野 大白话之Docker(叁):制作一个运行Tomcat服务端的Docker镜像 Github仅保留指定文件/文件夹当前Commit,删除所有历史记录,清除「敏感信息」 - 技术改变视野 将Tomcat、MySQL从Linux迁移到Windows的心路历程(干货):令人恐惧的字符编码 - 技术改变视野 Spring: java.lang.NoSuchMethodError: clearCache | ClassNotFoundException | Error during artifact deployment 思路及解决办法 - 技术改变视野 大白话之Java反射-初学最迷的概念:能干啥?咋用? 大白话之Java面向接口编程:最“正经”的中文实例讲解,看不懂来打我! - 技术改变视野 大白话 | 课堂实践:使用Iterator对数组进行遍历 大白话之fail-fast | fail-safe:为什么会有这个机制?它有什么作用? 刨根问底 | 大白话:在使用注解后,框架是怎么知道你哪个方法使用了注解的?用@RequestMapping注解举例详解! - 技术改变视野 大白话之必会Java Atomic | 线程一点也不安全(二):Atomic的ABA问题会导致什么情况?如何解决? 随笔 | 奇淫技巧 | Java:记return和短路运算符的妙用 - 技术改变视野 随笔 | Tomcat:续-从Linux迁移到Windows编码问题彻底解决 - 技术改变视野 大白话之AutoClosable接口 | try-with-resources:JDK1.7的新特性,提高重复回收效率 - 技术改变视野 大白话之Java多线程join方法:开局一张图,试学一分钟,你就费和我一样,理解介个方法 大白话之Java Stream流:将类数组流化,便捷批量修改,通俗讲解! Java 困扰三周の问题:使用byte[]或skip()方法读取字节流Stream文件尾部多/少/缺字节解决方法 - 技术改变视野
WebFilter-SpringBoot过滤器注解实例讲解 - 技术改变视野
adlered · 2019-12-09 · via 技术改变视野

简介

Filter也称之为过滤器,它是Servlet技术中最让人激动的技术,Web开发人员通过Filter技术,对Web服务器管理的所有Web资源:例如JSP,Servlet,静态图片文件或静态HTML文件等进行拦截,从而实现一些特殊的功能,例如实现URL级别的权限访问控制,过滤敏感词汇,压缩响应信息等一些高级功能。
可以在web.xml中配置过滤器的生效URL地址,它会过滤指定的URL地址经过的数据”/*”代表过滤所有的URL地址请求数据。
这样做的好处有什么呢,可以直接配置过滤所有的请求编码都设置为UTF-8,在response的时候也可以将响应编码也设置为UTF-8,这样就省去了写相同代码的步骤,优化代码。

Filter链

在一个Web应用中,可以开发编写多个Filter,这些Filter组合起来称之为一个Filter链。
Web服务器根据Filter在web.xml文件中的注册顺序,决定先调用哪个Filter,当第一个Filter的dofilter方法被调用时,web服务器会创建一个代表filter链的FilterChain对象传递给该方法,在doFilter()方法中,开发人员如果调用FilterChain对象的doFilter()方法,则Web服务器会检查FilterChain对象中是否还有Filter,如果有,则调用第二个Filter,如果没有,则调用目标资源。

Filter匹配

精确匹配:

1/路径/资源名

如:/index.html 、/hello/index.jsp 、 /client/LoginServlet

精确匹配只要在请求地址完全一样时才会调用Filter

路径匹配:

1/路径名/*

如:/hello/* 、/*

路径匹配只要是所请求的资源是在设置的路径下就会调用Filter

如:/hello/* 只要访问 项目根目录/hello/ 下的任意资源就会调用Filter

如: /* 只要访问 项目根目录下的资源就会调用Filter

后缀匹配:

1*.后缀名

如:*.jsp 、 *.html

后缀匹配只要访问的资源路径是以指定后缀结尾就会调用Filter

Filter的生命周期

Filter的创建好销毁都由Web服务器负责,Web应用程序启动时,Web服务器将创建Filter的实例化对象,并调用其init()方法,完成对象的初始化功能,从而为后续的用户请求做好拦截的准备工作,Filter对象只会创建一次,init()方法也只会执行一次。通过init()方法的参数,可获得代表当前Filter配置信息的FilterConfig的对象。

Web容器调用destroy()方法销毁Filter,destroy()方法在Filter的生命周期中仅执行一次;在destroy()方法中,可以释放过滤器使用的资源。

FilterConfig接口

用户在配置Filter时,可以使用<init-param>为Filter配置一些初始化参数,当Web容器实例化Filter对象,调用其init()方法时,会把封装了Filter初始化参数的filterConfig对象传递进来。因此开发人员在编写Filter时,通过filterConfig对象的方法,就可获得:

1String getFilterName()

得到Filter的名称。

1String getInitParameter(String name)

返回在部署描述中指定名称的初始化参数的值。如果不存在返回null

1Enumeration getInitParameterNames()

返回过滤器的所有初始化参数的名字的枚举集合。

1public ServletContext getServletContext()

返回Servlet上下文对象的引用。

使用

Filter的声明方式有两种:
第一种是使用注解的方式声明
第二种是在web.xml中使用标签的方式进行声明

注解Filter

使用@WebFilter(filterName = "过滤器名字", urlPatterns = "过滤地址", description = "描述")

举个栗子

 1    @Controller
 2    @WebFilter(filterName = "TestFilter", urlPatterns = "/*.do")
 3    public class TestFilter implements Filter {
 4
 5        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
 6            System.out.println("开始过滤2");
 7            chain.doFilter(req, resp);
 8        }
 9
10        public void init(FilterConfig config) throws ServletException {
11            System.out.println("创建filter对象2");
12        }
13
14        public void destroy() {
15            System.out.println("filter已经被销毁2");
16        }
17    }
18
19    @Controller
20    @WebFilter(filterName = "TestFilter2", urlPatterns = "/*.do")
21    public class TestFilter2 implements Filter {
22
23        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
24            System.out.println("开始过滤1");
25            chain.doFilter(req, resp);
26        }
27
28        public void init(FilterConfig config) throws ServletException {
29            System.out.println("创建filter对象1");
30        }
31
32        public void destroy() {
33            System.out.println("filter已经被销毁1");
34        }
35    }

通过注解的方式配置Filter过滤器

如果在SpringBoot里最好加上一个@Controller标签,Filter的执行顺序可以使用@Order(i)决定Filter的执行顺序i的值越大执行顺序越靠前。

在web.xml里配置的Filter是由上下顺序决定的。

web.xml配置Filter

再举个栗子

 1    <!-- Filter文件配置 -->
 2    <filter>
 3        <filter-name>TestFilter</filter-name>
 4        <filter-class>cn.zlys.service.TestFilter</filter-class>
 5    </filter>
 6    <filter-mapping>
 7        <filter-name>TestFilter</filter-name>
 8        <url-pattern>/*</url-pattern>
 9    </filter-mapping>
10    <!-- Filter的执行顺序和配置的顺序有关 -->
11    <filter>
12        <filter-name>TestFilter2</filter-name>
13        <filter-class>cn.zlys.service.TestFilter2</filter-class>
14    </filter>
15    <filter-mapping>
16        <filter-name>TestFilter2</filter-name>
17        <url-pattern>/*.do</url-pattern>
18    </filter-mapping>

在web.xml中配置的好处是在项目发布后可以不更改项目源码就可以更改Filter执行的URL地址或者是Filter的class路径。并且通过web.xml配置Filter还可以选择过滤的方式,比如只过滤请求或者过滤ERROR。

使用dispatcher标签决定过滤的方式,一共有REQUEST、ERROR、FORWARD、INCLUDE,分别是请求错误转发包含,包含是JSP里的include标签。

在Filter中也有init-param标签,可以在项目初始化时获取数据,比如说在init-param标签里配置编码格式为UTF-8格式,这样的话就可以使项目的编码动态的更改,如果想要在项目发布后更改项目的编码格式,直接更改web.xml中init-param里的数据就可以了。

总结

Filter的发明真的是便利的我们的生活,可以省略不必要的代码,如果是请求的编码确认可以不用写很多遍,因为如果Serlvet过多时,在每个Servlet都要写设置编码格式,如果想要更改编码格式的时候就需要每个 Servlet都重写一遍,但是有了Filter就可以只写一遍,就实现了在每个Servlet里都更改了请求编码格式和响应编码格式。

Filter不仅可以通过url-pattern来拦截指定url地址匹配的资源,而且还可以通过servlet-name来指定拦截哪个指定的servlet(专门为某个servlet服务,servlet-name对应Servlet相关配置)