• 一文看懂Filter过滤器


    什么是过滤器?

    在web中的过滤器可以对游览器的请求进行过滤,对请求进行拦截,然后做出相应小狐狸,实现很多特殊功能,例如:登录控制,权限管理,过滤敏感词汇等

    过滤器原理

    当我们使用过滤器的时候,过滤器会对游览器的请求进行过滤,过滤器可以动态的分为3个部分

    1. 放行之前的代码
    2. 放行
    3. 放行之后的代码
    • 第一部分的代码会对游览器请求进行第一次过滤,然后继续执行。
    • 第二部分代码就是将游览器请求放行,如果还有过滤器,那么就继续交给下一个过滤器。
    • 第三部分代码就是对返回的Web资源再次进行过滤处理

    在这里插入图片描述

    实现Filter的时候,要继承Filter接口

    在这里插入图片描述

    我们来看一下Filter接口里面有什么东西:

    在这里插入图片描述

    首先可以看到是servlet这个包里面的,不能搞错了。

    然后里面有三个方法,init, doFilter, destroy

    doFilter方法没有实现,所以我们必须要重写doFilter方法。

    Filter使用

    @Slf4j
    @WebFilter(filterName = "AFilter", urlPatterns = "/*")
    public class TestFilter implements Filter {
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            System.out.println("对request进行过滤");
            filterChain.doFilter(servletRequest, servletResponse);
            System.out.println("对response进行过滤");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    我们随意输入一个url地址。

    在这里插入图片描述

    于是我们得出结论,过滤器并不会管资源是否存在,只会对配置的拦截路径进行拦截。拦截不仅会对请求进行拦截, 而且会对响应进行拦截

    使用@WebFilter拦截路径

    在这里插入图片描述

    • filterName:该filter的名字
    • initParams:初始化参数
    • displayName:filter显示名称
    • servletNames:指定对哪些servlet进行过滤
    • asyncSupported:是否支持异步模式
    • urlPatterns:指定拦截路径
    • value:指定拦截路径

    urlPatterns和value是一样的,只能配置一个,不然就会出错

    xml方式(了解就行了,几乎不会用)

    <filter>
        <filter-name>myFilterfilter-name>
        <filter-class>com.example.reggie_delivery.TestFilterfilter-class>
    filter>
    <filter-mapping>
        <filter-name>AFilterfilter-name>
        <url-pattern>/*url-pattern>
    filter-mapping>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    过滤器Filter生命周期

    Filter有三个阶段

    1. 初始化阶段,当服务器启动,服务器就会读取配置文件,扫描注解,然后创建Filter
    2. 拦截和过滤阶段,只要请求资源的路径和拦截的路径相同,过滤器就会对请求进行过滤,这个阶段在服务器运行阶段会不停的循环
    3. 销毁阶段:当服务器tomcat关闭的时候,服务器创建的Filter也会随之销毁

    FilterConfig和FilterChain

    FilterConfig

    在这里插入图片描述

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

    import javax.servlet.*;
    import java.io.IOException;
    import java.util.Enumeration;

    public class MyFilterConfig implements Filter {

    import javax.servlet.*;
    import java.io.IOException;
    import java.util.Enumeration;
     
    public class MyFilterConfig implements Filter {
     
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            System.out.println("-----------获取全部key:value------------");
            //得到所有配置参数的名字
            Enumeration<String> names = filterConfig.getInitParameterNames();
            while (names.hasMoreElements()) {
                //得到每一个名字
                String name = names.nextElement();
                System.out.println(name+" = "+filterConfig.getInitParameter(name));
            }
            System.out.println("-----------end.....------------");
        }
     
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        }
     
        @Override
        public void destroy() {
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    xml配置

    <filter>
            <filter-name>myFilterConfigfilter-name>
            <filter-class>com.clucky.filter.MyFilterConfigfilter-class>
            <init-param>
                <param-name>driverparam-name>
                <param-value>com.mysql.jdbc.Driverparam-value>
            init-param>
            <init-param>
                <param-name>urlparam-name>
                <param-value>jdbc:mysql://localhost:3306/equip_employ_manage?serverTimezone=GMTparam-value>
            init-param>
            <init-param>
                <param-name>usernameparam-name>
                <param-value>rootparam-value>
            init-param>
            <init-param>
                <param-name>passwordparam-name>
                <param-value>rootparam-value>
            init-param>
        filter>
        <filter-mapping>
            <filter-name>myFilterConfigfilter-name>
            <url-pattern>/*url-pattern>
        filter-mapping>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    在这里插入图片描述

    所以FilterConfig就是用来读取配置文件的。

    什么是ServletContext?

    用一张图简要的表明:

    在这里插入图片描述

    FilterChain

    强转成

    在这里插入图片描述

    HttpServletRequest和HttpServletResponse

    然后就可以使用他们的方法了。

    filterChain.doFilter()方法可以让Filter进入下一个Filter继续进行过滤。
    在这里插入图片描述

    多个Filter的执行顺序:

    • 如果我们是在web.xml中配置的过滤器,那么过滤器的执行顺序就是在web配置的顺序,配置在上面那么就会先执行。
    • 如果我们是使用@WebFilter进行配置的,那么执行顺序就是字符比较顺序来执行,例如有2个过滤器,一个是AFilter,一个是BFilter,那么AFilter就会先执行。
    • 如果注解和xml混用,那么在web.xml中配置的会先执行。
    <filter>
        <filter-name>filter03filter-name>
        <filter-class>com.clucky.filter.Filter03filter-class>
    filter>
    <filter-mapping>
        <filter-name>filter03filter-name>
        <url-pattern>/*url-pattern>
    filter-mapping>
    <filter>
        <filter-name>filter01filter-name>
        <filter-class>com.clucky.filter.Filter01filter-class>
    filter>
    <filter-mapping>
        <filter-name>filter01filter-name>
        <url-pattern>/*url-pattern>
    filter-mapping>
    <filter>
        <filter-name>filter02filter-name>
        <filter-class>com.clucky.filter.Filter02filter-class>
    filter>
    <filter-mapping>
        <filter-name>filter02filter-name>
        <url-pattern>/*url-pattern>
    filter-mapping>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    最后在SpringBoot的启动函数上面要加上@ServletComponentScan注解

  • 相关阅读:
    数据结构-------队列
    【C++初阶(二)缺省参数与函数重载】
    keycloak~RequiredActionProvider的使用
    android studio platform使用体验分享(as无法跳转c/c++等native源码的福音,强烈推荐)
    react事件与原生事件的区别
    【MySQL基础】常用指令详解
    39-Java方法的参数传递的小案例
    53. 最大子数组和
    SaaSBase:什么是石墨文档?
    eyb:SpringSecurity:Oauth2协议
  • 原文地址:https://blog.csdn.net/qq_61039408/article/details/126054904