Filter 介绍、实现、如何工作

本文详细介绍了Servlet Filter的概念及其在Web应用程序中的应用。Filter作为Servlet技术的一部分,可以用来预处理请求或后处理响应,常用于实现用户授权、日志记录等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Filter介绍

Filter

Filter可以认为是Servlet的“加强版”,它主要用于对用户的请求进行预处理,也可以对Response进行后处理,是一个处理链

*一个Filter可以负责拦截多个请求、响应
一个请求、响应也可以被多个Filter拦截*

Filter的一些用处:

  • 在HttpServletRequest到达Servlet之前,拦截请求,根据需要进行检查、或修改请求头和数据
  • 在HttpServletResponse送往客户端前,拦截响应,根据需要进行检查、或修改响应头和数据

Filter常见的几个种类

  • 用户授权的filter:负责检查用户请求,过滤非法请求
  • 日志Filter:记录某些特殊的用户请求
  • 负责解码的Filter:包括对非标准编码的请求解码
  • 可以改变XML内容的XSLT Filter等

Filter实现

创建Filter类

创建Filter必须实现javax.servlet.Filter接口,该接口定义了三个方法:
这里写图片描述

  • void init(FilterConfig config) :用于完成Filter的初始化操作
  • void destroy() :Filter 对象销毁时调用此方法,用于回收一些资源
  • void doFilter(ServletRequest request , ServletResponse resopnse , FilterChain chain) :实现过滤功能
    以上只是对这三个方法的简单介绍,后面进行详细介绍

以简单的日志Filter举例,介绍Filter的创建


@WebFilter(filterName="log",urlPatterns={"/*"})
public class LogFilter implements Filter {

    //用于访问Filter的配置信息
    private FilterConfig config;

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        this.config=config;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // TODO Auto-generated method stub
        ServletContext context = this.config.getServletContext();
        long before = System.currentTimeMillis();
        HttpServletRequest hsrequest = (HttpServletRequest) request;
        System.out.println("Filter拦截到的请求路径:"+hsrequest.getServletPath());
        //Filter是链式处理,将请求转发到下一Filter或目的地址
        chain.doFilter(request, response);
        long after = System.currentTimeMillis();
        System.out.println("请求定位到:"+hsrequest.getRequestURI()+" 所花费时长: "+ (after-before));
    }

    @Override
    public void destroy() {
        // TODO Auto-generated method stub
        this.config= null;
    }

}

配置Filter
(1) web.xml配置文件:

    <filter>
        <filter-name>log</filter-name>
        <filter-class>lee.LogFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>GBK</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>log</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

(2)@WebFilter注解修饰Filter实现类
@WebFilter常用属性:

  • asyncSupported : 指定该Filter是否支持异步操作模式
  • displayName : 指定Filter的显示名
  • filterName : 指定该filter的名称
  • initParams : 为该Filter配置参数
  • servletNames : 可指定多个Servlet名称,用于指定该Filter仅对这几个Servlet执行过滤
  • urlPatterns / value : 这两个属性作用完全相同,指定该Filter所拦截过滤的url

Filter如何工作

Filter相关的类图
这里写图片描述

(1)FilterChain对象可以灵活地控制请求的流转

(2)在Tomcat容器中,FilterConfig和FilterChain的实现类分别是ApplicationFilterConfig和ApplicationFilterChain,Filter类由用户实现

(3)FilterChain是Filter的核心,FilterChain对象保存了直到最终的Servlet对象的所有Filter对象,这些对象都保存在ApplicationFilterChain对象的filters数组中。在FilterChain链上每执行一个Filter对象,数组的当前计数都会加 1,直到计数等于数组的长度,当FilterChain上所有的Filter对象执行完成后,就会执行最终的Servlet。所以ApplicationFilterChain对象中会持有Servlet对象的引用

(4)Filter接口定义的三个方法:

  • void init(FilterConfig config) : 初始化接口,在用户自定义的Filter初始化时被调用,它与Servlet的init方法作用一样,FilterConfig 与ServletConfig也类似,两者都能获取到容器的环境类ServletContext对象,FilterConfig的 getInitParameters()方法能获取在< filter >下配置的 < init-param >参数值

  • doFilter(ServletRequest request , ServletResponse resopnse , FilterChain chain) : 在每个用户的请求进来时,这个方法会被调用,并在Servlet的service方法之前被调用。而FilterChain就代表着当前的整个请求链,所以通过调用FilterChain.doFilter(request, response)可以将请求继续传递下去。如果想拦截这个请求,可以不调用FilterChain.doFilter(request, response),当前Filter类的doFilter(ServletRequest request , ServletResponse resopnse , FilterChain chain)方法执行结束后,则这个请求就直接返回。Filter链是递归执行的,且是一种责任链设计模式

  • void destroy() :Filter对象销毁时,此方法调用。注意:当Web容器调用这个方法后,容器会再调用一次doFilter方法

Filter执行顺序
这里写图片描述

ApplicationFilterChain类可以按照web.xml中Filter定义的先后顺序将多个Filter串联起来,组成一个链

Filter执行时序图
这里写图片描述

参考:
《轻量级Java EE 企业应用实践 –Struts2+Spring+Hibernate》
《深入分析Java Web 技术内幕》
http://docs.oracle.com/javaee/6/api/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值