Filter 过滤器接口详解

目录

1、Filter接口描述

2、如何使用Filter接口定义一个过滤器?

3、Filter接口的工作原理

4、Filter、FilterChain、FilterConfig、FilterRegistration、FilterRegistration.Dynamic 接口综述

(1)如何使用FilterConfig接口对Filter实例进行配置?

(2)如何在程序中动态注册和配置Filter实例?

5、过滤器和拦截器的区别


1、Filter接口描述

        Servlet Filter接口是Java Servlet API提供的一种标准接口,用于在Servlet容器中对HTTP请求和响应进行拦截和处理。它可以用于访问控制、安全验证、日志记录、字符编码转换等功能。

        Filter接口定义了三个方法:

  1. init方法:在Filter被初始化时调用,用于进行一些初始化操作。// 过滤器的初始化
  2. doFilter方法:对HTTP请求和响应进行拦截和处理的核心方法,可以对请求进行修改或过滤,也可以对响应进行修改或增强。// 核心方法,它的参数request,response,chain
  3. destroy方法:在Filter被销毁时调用,用于进行一些清理操作。

        Filter接口的实现类需要在web.xml文件中进行配置,并指定要拦截的URL模式,以及要使用的过滤器类。当符合URL模式的请求到达Servlet容器时,就会被该过滤器进行拦截和处理。

Servlet Filter接口的主要作用包括:

  1. 对请求和响应进行拦截和处理:Filter可以拦截Web应用程序中的请求和响应,对它们进行处理,并将它们传递给下一个Filter或Servlet。Filter可以在请求到达目标Servlet之前对请求进行修改,或在响应发送到客户端之前对响应进行修改,从而实现对请求和响应的拦截和处理。
  2. 实现功能增强:Filter可以在请求和响应中添加、删除或修改内容,从而实现对Web应用程序的功能增强。例如,Filter可以对请求进行身份验证,对响应进行压缩,或者对请求和响应进行日志记录等。
  3. 统一处理逻辑:Filter可以将Web应用程序中的一些公共逻辑进行抽象和封装,从而实现统一处理。例如,Filter可以对所有请求进行字符编码转换,或者对所有请求和响应进行异常处理等。

        Servlet Filter接口的设计可以帮助开发者将一些通用的处理逻辑从具体的Servlet中抽离出来,实现更加模块化和可复用的代码。这样可以减少代码重复,提高开发效率,同时也可以提高Web应用程序的可维护性和可扩展性。

2、如何使用Filter接口定义一个过滤器?

        以下是一个简单的使用 @WebFilter 注解定义过滤器的示例:

@WebFilter(filterName = "myFilter", urlPatterns = { "/hello/*" })
public class MyFilter 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() {
        // 过滤器销毁代码
    }
}

        在上面的例子中,@WebFilter 注解指定了过滤器名称为 myFilter,过滤器的 URL 模式为 /hello/*,表示该过滤器会拦截所有以 /hello/ 开头的 URL。过滤器的处理逻辑在 doFilter() 方法中实现。

        @WebFilter 是用于在 Servlet 3.0 之后的版本中定义一个过滤器(Filter)。

        使用 @WebFilter 注解可以将一个类声明为一个过滤器,并指定过滤器的名称、URL 模式和过滤器顺序等信息。

        @WebFilter 注解有以下常用属性:

  • filterName:过滤器的名称,用于在 web.xml 文件或其他注解中引用该过滤器。
  • value/urlPatterns:过滤器的 URL 模式,可以是一个字符串数组或字符串,用于指定该过滤器所处理的 URL。
  • dispatcherTypes:指定该过滤器所处理的请求类型,如 REQUEST、FORWARD、INCLUDE 和 ASYNC 等。
  • initParams:过滤器的初始化参数,用于在过滤器初始化时设置一些配置参数。
  • asyncSupported:指定该过滤器是否支持异步请求处理。

3、Filter接口的工作原理

        Filter的工作流程如下:

Filter 过滤器接口详解_第1张图片

  1. 客户端请求访问容器内的 Web 资源。
  2. Servlet 容器接收请求,并针对本次请求分别创建一个 request 对象和 response 对象。
  3. 请求到达 Web 资源之前,先调用 Filter 的 doFilter() 方法,检查 request 对象,修改请求头和请求正文,或对请求进行预处理操作。
  4. 在 Filter 的 doFilter() 方法内,调用 FilterChain.doFilter() 方法,将请求传递给下一个过滤器或目标资源。
  5. 目标资源生成响应信息返回客户端之前,处理控制权会再次回到 Filter 的 doFilter() 方法,执行 FilterChain.doFilter() 后的语句,检查 response 对象,修改响应头和响应正文。
  6. 响应信息返回客户端。

        Filter 实例在 Servlet 容器启动时创建,由 Servlet 容器负责创建和管理。创建时,会使用 Filter 的默认构造函数创建一个新的实例。当有 HTTP 请求到达 Web 应用程序时,Servlet 容器会使用这个实例来处理请求。

        下面是Tomcat 中 Filter 实例创建和执行的源码示例:// 所谓的拦截只是一个先后顺序的实现

public class ApplicationFilterChain implements FilterChain {
    // Filter 实例列表
    private Filter[] filters;
    // Filter 实例索引
    private int pos;
    // ...

    // 构造函数
    public ApplicationFilterChain(Filter[] filters) {
        this.filters = filters;
        this.pos = 0;
    }

    // 调用下一个 Filter
    public void doFilter(ServletRequest request, ServletResponse response)
            throws IOException, ServletException {
        // ...
        if (this.pos < this.filters.length) {
            Filter filter = this.filters[this.pos++];
            filter.doFilter(request, response, this);
        } else {
            // 如果所有 Filter 都已经执行完成,调用目标 Servlet
            servlet.service(request, response);
        }
    }
}

4、Filter、FilterChain、FilterConfig、FilterRegistration、FilterRegistration.Dynamic 接口综述

        Filter、FilterChain、FilterConfig、FilterRegistration、FilterRegistration.Dynamic都是与Filter相关的接口或类,它们分别代表了Filter的不同方面和功能。以下是它们的具体介绍:

  1. Filter:Filter是一个接口,定义了对HTTP请求和响应进行拦截和处理的方法。实现Filter接口的类可以在Web应用程序中拦截HTTP请求和响应,并对它们进行预处理、后处理等。
  2. FilterChain:FilterChain是一个接口,代表一个过滤器链。当一个HTTP请求被多个Filter拦截时,FilterChain将这些Filter串起来,并按照它们在web.xml文件中的声明顺序进行调用。
  3. FilterConfig:FilterConfig是一个接口,它提供了对Filter的配置信息的访问。在Filter的init()方法中,可以通过FilterConfig获取Filter的初始化参数、ServletContext等信息。
  4. FilterRegistration:FilterRegistration是一个接口,它提供了对Filter的注册和配置的方法。通过FilterRegistration可以设置Filter的名称、URL模式、初始化参数等信息。
  5. FilterRegistration.Dynamic:FilterRegistration.Dynamic是FilterRegistration的子接口,它提供了动态配置Filter的方法。通过FilterRegistration.Dynamic可以动态添加、删除和修改Filter的URL模式、初始化参数等信息。

        Filter实现类可以通过这些接口或类访问Filter的配置信息、管理Filter的注册和调用顺序。

(1)如何使用FilterConfig接口对Filter实例进行配置?

        FilterConfig接口是Java Servlet规范中定义的一个接口,用于为Filter实例提供配置信息。可以通过以下步骤来使用FilterConfig接口对Filter实例进行配置:// 在初始化方法中使用配置

  1. 在Filter实现类中实现init()方法,并接收FilterConfig对象作为参数
  2. 在init()方法中,可以使用FilterConfig对象提供的方法获取Filter的配置信息。例如,可以使用getInitParameter()方法获取初始化参数,使用getServletContext()方法获取ServletContext对象等等。
  3. 使用获取到的配置信息对Filter实例进行配置。例如,可以根据获取到的初始化参数设置Filter的属性值,或者根据获取到的ServletContext对象获取其他组件并进行初始化。
  4. 在完成配置后,可以在init()方法的最后调用FilterConfig对象的getFilterName()方法获取Filter的名称,并输出一条日志来确认Filter已成功初始化。

        下面是一个示例代码片段,演示如何使用FilterConfig接口对Filter实例进行配置:

public class MyFilter implements Filter {
    private String myParam;

    public void init(FilterConfig config) throws ServletException {
        myParam = config.getInitParameter("myParam");

        // 对Filter进行配置
        // ...

        // 输出日志确认Filter已成功初始化
        String filterName = config.getFilterName();
        System.out.println("Filter " + filterName + " initialized.");
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // 执行过滤操作
        // ...
    }

    public void destroy() {
        // 清理资源
        // ...
    }
}

(2)如何在程序中动态注册和配置Filter实例?

        在Java Servlet API中,Filter是一个可以在请求进入Servlet之前或Servlet处理完请求之后执行一些操作的组件。

        1)编写Filter类:首先需要编写Filter类来实现Filter接口,重写其doFilter方法,这个方法中实现对请求进行处理的逻辑。例如:

public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // Filter初始化时执行的代码
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 处理请求的代码
        filterChain.doFilter(servletRequest, servletResponse);
        // 处理响应的代码
    }

    @Override
    public void destroy() {
        // Filter销毁时执行的代码
    }
}

        2)动态注册Filter:在Servlet的init方法中调用ServletContext的addFilter方法动态注册Filter,如下所示:// 在Servlet中进行注册

public class MyServlet extends HttpServlet {
    @Override
    public void init(ServletConfig config) throws ServletException {
        FilterRegistration.Dynamic dynamicFilter = config.getServletContext().addFilter("myFilter", MyFilter.class);
        dynamicFilter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // Servlet处理请求的代码
    }
}

        其中,addFilter方法返回一个FilterRegistration.Dynamic对象,可以通过该对象配置Filter的初始化参数、URL模式等信息。addMappingForUrlPatterns方法可以指定Filter要处理的URL模式,也可以通过其他方法设置Filter的初始化参数等信息。

        3)动态配置Filter:通过FilterRegistration.Dynamic对象可以动态配置Filter的初始化参数、URL模式等信息。例如:

public class MyServlet extends HttpServlet {
    @Override
    public void init(ServletConfig config) throws ServletException {
        FilterRegistration.Dynamic dynamicFilter = config.getServletContext().addFilter("myFilter", MyFilter.class);
        dynamicFilter.setInitParameter("paramName", "paramValue");
        dynamicFilter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/path/*");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // Servlet处理请求的代码
    }
}

        以上就是动态注册和配置Filter的步骤。需要注意的是,动态注册和配置Filter只能在Servlet容器启动时执行,不能在运行时动态修改。如果需要动态修改Filter的配置,需要重新启动Servlet容器。

5、过滤器和拦截器的区别

        过滤器(Filter)和拦截器(Interceptor)都是用于在Web应用中对请求进行处理的组件,它们的目的都是为了提供一种可重用的、可配置的、通用的请求处理机制。虽然它们的目的相同,但是它们之间还是存在一些区别:// 一个是JavaEE规范,一个是Spring实现

  1. 使用位置不同:过滤器是基于Servlet规范的,工作在Servlet容器内部(Servlet的service方法之前),对客户端请求进行预处理和后处理;而拦截器是基于Java的反射机制由Spring框架实现(service方法之中,对Controller的请求进行拦截处理。
  2. 执行时机不同:过滤器在Servlet容器内部的请求处理链中执行,也就是在请求进入Servlet之前或者Servlet处理完请求之后执行;而拦截器在请求进入Controller之前或者Controller处理完请求之后执行。

        一张图,非常的清除的描述了过滤器和拦截器的区别:

Filter 过滤器接口详解_第2张图片

        至此,Filter接口的描述到此结束。

你可能感兴趣的:(Java,Servlet,Servlet,Filter接口)