"[图片] 简介 Filter 也称之为过滤器,它是 Servlet 技术中最让人激动的技术,Web 开发人员通过 Filter 技术,对 Web 服务器管理的所有 Web 资源:例如 JSP,Servlet,静态图片文件或静态 HTML 文件等进行拦截,从而实现一些特殊的功能,例如实现 URL 级别的权限访问控制,过滤 .."

WebFilter-SpringBoot 过滤器注解实例讲解

v2a0ed46ccaa50311b2b8c435ef1277639hd.jpg

简介

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 匹配

精确匹配:

/ 路径 /资源名

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

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

路径匹配:

/ 路径名 /*

如:/hello/* 、/*

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

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

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

后缀匹配:

*. 后缀名

如:*.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对象的方法,就可获得:

String getFilterName()

得到 Filter 的名称。

String getInitParameter(String name)

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

Enumeration getInitParameterNames()

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

public ServletContext getServletContext()

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

使用

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

注解 Filter

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

举个栗子

    @Controller
    @WebFilter(filterName = "TestFilter", urlPatterns = "/*.do")
    public class TestFilter implements Filter {

        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
            System.out.println("开始过滤 2");
            chain.doFilter(req, resp);
        }

        public void init(FilterConfig config) throws ServletException {
            System.out.println("创建 filter 对象 2");
        }

        public void destroy() {
            System.out.println("filter 已经被销毁 2");
        }
    }

    @Controller
    @WebFilter(filterName = "TestFilter2", urlPatterns = "/*.do")
    public class TestFilter2 implements Filter {

        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
            System.out.println("开始过滤 1");
            chain.doFilter(req, resp);
        }

        public void init(FilterConfig config) throws ServletException {
            System.out.println("创建 filter 对象 1");
        }

        public void destroy() {
            System.out.println("filter 已经被销毁 1");
        }
    }

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

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

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

web.xml 配置 Filter

再举个栗子

    <!-- Filter 文件配置 -->
    <filter>
        <filter-name>TestFilter</filter-name>
        <filter-class>cn.zlys.service.TestFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>TestFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!-- Filter 的执行顺序和配置的顺序有关 -->
    <filter>
        <filter-name>TestFilter2</filter-name>
        <filter-class>cn.zlys.service.TestFilter2</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>TestFilter2</filter-name>
        <url-pattern>/*.do</url-pattern>
    </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 相关配置)

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    2165 引用 • 7415 回帖 • 1020 关注
  • 代码
    143 引用 • 416 回帖 • 1 关注
感谢    关注    收藏    赞同    反对    举报    分享
回帖    
请输入回帖内容...