聊聊Filter

150 阅读3分钟

1. Filter概念

过滤器: 过筛子,符合条件的过去,不符合条件不能过去.

生活比喻: 安检,检查安全的人与物才可以通过放行

程序: 客户端需要访问服务器的目标资源,在客户端和服务器资源之间设置过滤器, 符合要求放行

2. 创建Filter

2.1 web.xml里配置

public class MyFilter1 implements Filter{
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    	chain.doFilter(request,response);
    }

    @Override
    public void destroy() {
    }
}
<filter>
    <filter-name>myFilter1</filter-name>
    <filter-class>com.itheima.filter.MyFilter1</filter-class>
</filter>

<filter-mapping>
    <filter-name>myFilter1</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

2.2 使用注解创建,@webFilter+@Configuration

@WebFilter(urlPatterns = "/filter/*")
public class HelloFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        chain.doFilter(request,response);
    }

    @Override
    public void destroy() {
    }
}

2.3FilterRegisterBean+Filter去注册

如何注册
spring 找initializar去获取filter的definition,给他包装成一个filter,然后通过register的add
reistration方法加到servletContext中
servletContextinitializerregisterBean实现了Initializer,

3. Filter的生命周期

  • 过滤器对象的创建,Tomcat服务器启动时调用

    • init(FilterConfig config)过滤器对象被创建的时候调用,FilterConfig 对象tomcat引擎创建
  • 过滤器执行过滤的方法,过滤被访问资源的时候,必须是被过滤器过滤器的资源

    • doFilter(request,response)
  • 过滤器对象销毁的方法,销毁之前调用,服务器关闭或者项目从Tomcat undeploy

    • destroy()

4. Filter的url-pattern配置

  • 完全匹配
<!--
    过滤资源,只有hello
    绝对匹配 <url-pattern>/hello</url-pattern>
    只能过滤指定的资源
-->
<url-pattern>/hello</url-pattern>

  • 目录匹配
<!--
   目录匹配,过滤器中最常见
   /abc/*  过滤abc目录下的所有资源
   一次过滤一片资源
   过滤后台资源 /admin/*
-->
<url-pattern>/admin/*</url-pattern>

  • 后缀名匹配
<!--
  后缀名匹配,一般不使用
  *.jsp  访问所有jsp文件
-->
<url-pattern>*.jsp</url-pattern>

5. Filter的四种拦截方式

四种拦截形式 默认是REQUEST

  • 请求拦截: REQUEST 默认配置,拦截从客户端发来的请求
  • 转发拦截: FORWARD Servlet1转发到Servlet2,就会拦截
  • 包含拦截: INCLUDE 当一个JSP页面包含另一个JSP页面,拦截
  • 错误拦截: ERROR 程序出现500错误,跳转到一个页面去,拦截

下面三种是服务器内部行为,比较安全,一般不拦截

6. 中文乱码过滤器

@WebFilter(urlPatterns = "/*")
public class ChineseFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    /**
     * 每次拦截执行的方法
     * 方法的参数 servletRequest,servletResponse传递到Servlet的doGet方法
     * 过滤器中,设置request对象使用编码表
     * 所有的Servlet都受益
     */
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("utf-8");
        servletResponse.setContentType("text/html;charset=utf-8");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
    }
}

7. 过滤器链 FilterChain的执行过程(责任链模式)

生活中的过滤器链:

  • 从 脏水 --> -->UF超滤膜 --> PP棉 -->前置活性炭 --> RO膜 --> 纳米晶须活性炭 --> 出纯水

Filter中的过滤器链 FilterChain: 由Tomcat引擎创建对象

作用: 维护过滤器执行顺序

多个过滤器的先后执行顺序

  1. web.xml配置

    和配置文件的编写顺序决定运行的顺序,准确的说法是,根据mapping的顺序决定 (由上到下执行)

  2. 注解开发

    注解开发没有配置文件的 按照类名的自然顺序决定: A-B-C 如果存在配置文件,配置文件优先

责任链模式在源码中如何体现

责任链主要由filterChain去维护,里面维护的是一个filterconfig数组,filterconfig中拿到我们的filter,然后再进行执行