过滤器(Filter)和拦截器(Interceptor)在Web开发中至关重要,它们能有效地预处理和后处理请求与响应。本文深入解析它们的机制、配置和典型应用,助你在项目中高效应用并区分这两种强大工具。

过滤器(Filter)

过滤器是一种用于在请求到达 servlet 或响应从 servlet 返回之前对请求或响应进行预处理或后处理的机制。过滤器是基于 Servlet 规范的,通常用于 web 应用程序中。它们的主要特点和用途包括:

过滤器的用途:

  • 身份验证与授权:验证用户身份,检查用户是否有权限访问某些资源。
  • 日志记录和审计:记录请求的详细信息,如请求 URL、参数、执行时间等。
  • 输入校验和清理:对请求参数进行验证和清理,防止 SQL 注入、XSS 攻击等。
  • 压缩和解压缩:对响应数据进行压缩,提高传输效率。

工作机制

过滤器是基于 Servlet 规范的,在请求处理链中,过滤器可以在请求到达 servlet 前、在响应返回客户端前对请求和响应进行处理。过滤器通过过滤链(Filter Chain)实现,可以链式调用多个过滤器,按顺序执行。

执行顺序

过滤器可以在 web.xml 文件中配置,也可以通过注解配置,多个过滤器可以链式调用,按照配置的顺序执行。

配置方式

web.xml 配置: 在 web.xml 文件中配置过滤器及其映射。

<filter>
    <filter-name>MyFilter</filter-name>
    <filter-class>com.example.MyFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

注解配置(推荐): 使用 @WebFilter 注解进行配置。

@WebFilter(filterName = "MyFilter", urlPatterns = "/*")
public class MyFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // 过滤逻辑
        chain.doFilter(request, response); // 调用下一个过滤器或目标资源
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化逻辑
    }

    @Override
    public void destroy() {
        // 销毁逻辑
    }
}

生命周期

过滤器在 web 容器启动时被初始化,在容器关闭时被销毁。

典型实现

在 Java 中,过滤器通常通过实现 javax.servlet.Filter 接口来实现。

拦截器(Interceptor)

拦截器通常用于面向切面编程(AOP)或特定框架(如 Spring MVC,Struts2)中,用于在方法调用之前和之后进行拦截处理。它们的主要特点和用途包括:

拦截器的用途

  • 日志记录:记录方法调用的详细信息,包括方法名、参数、执行时间等。
  • 权限检查:在方法执行之前检查用户权限,决定是否允许执行该方法。
  • 事务管理:在方法调用前后进行事务管理,如开启和提交事务。
  • 性能监控:监控方法执行时间,收集性能数据。

工作机制

拦截器通常用于面向切面编程(AOP)或特定框架中,用于在方法调用之前和之后进行处理。拦截器可以在方法执行前、方法执行后或方法抛出异常时进行处理。

执行顺序

拦截器可以在框架配置文件中配置,或者通过注解配置,执行顺序可以通过配置文件或注解的优先级来控制。

配置方式

Spring MVC 中的拦截器: 配置方式可以通过 Java 配置或 XML 配置。

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
    }
}

Spring 拦截器实现: 实现 HandlerInterceptor 接口。

public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        // 在请求处理之前进行调用
        return true; // 返回 true 则继续处理,返回 false 则中断请求
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
        // 在请求处理之后、视图渲染之前进行调用
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
                                Exception ex) throws Exception {
        // 在整个请求结束之后调用
    }
}

生命周期

拦截器通常在方法调用前后执行,可以进行更细粒度的控制,如在方法执行前、方法执行后或方法抛出异常时进行处理。

典型实现

在 Spring 中,拦截器通常通过实现 HandlerInterceptor 接口来实现。 在 Struts2 中,拦截器通过实现 Interceptor 接口来实现。

详细对比

特点 过滤器(Filter) 拦截器(Interceptor)
应用层次 Web 层次,基于 Servlet 规范 业务逻辑层次,依赖于具体框架(如 Spring MVC)
处理对象 HTTP 请求和响应 方法调用
配置方式 web.xml 配置或注解配置 框架配置文件或注解配置
适用场景 身份验证、日志记录、输入校验、数据压缩等 日志记录、权限检查、事务管理、性能监控等
生命周期 在容器启动时初始化,关闭时销毁 方法调用前后,细粒度控制
实现方式 实现 javax.servlet.Filter 接口 实现 HandlerInterceptor 接口(Spring MVC)

对比总结

应用层次:过滤器应用于 web 层面,对所有请求和响应进行处理;拦截器应用于业务逻辑层面,对特定方法或控制器的调用进行处理。 灵活性:拦截器通常比过滤器更灵活,可以对方法调用进行更细粒度的控制。 依赖性:过滤器是基于 Servlet 规范的,独立于具体框架;拦截器通常依赖于具体的框架(如 Spring,Struts2)。

选择建议

  • 使用过滤器:
    • 需要对所有 HTTP 请求和响应进行统一处理。
    • 进行通用的预处理或后处理,如身份验证、数据压缩等。
  • 使用拦截器:
    • 需要对特定的业务逻辑进行前后处理。
    • 进行细粒度的控制,如事务管理、方法调用的权限检查。

转载自开思通智网:https://www.opensnn.com/os/article/10000804