微知识:过滤器和拦截器的区别?

本文发布于 2024年09月23日,阅读 11 次,点赞 0 次,归类于 微知识

1、来源不同

过滤器是 Servlet 规范中定义的一部分,它可以对客户端(浏览器)的请求和服务器的响应进行过滤操作。

拦截器是基于 Spring 等框架提供的一种机制,主要用于对特定的请求进行拦截和处理。

2、触发时机不同

过滤器执行顺序: 过滤器的执行顺序与它们在 web.xml 文件中或注解中的配置顺序有关,先配置的过滤器先执行。如果有多个过滤器,它们会按照顺序依次对请求进行过滤处理,然后再将请求传递给目标资源。响应时,也会按照相反的顺序依次经过各个过滤器的处理。

拦截器执行顺序: 拦截器的执行顺序与它们在 Spring 配置中的注册顺序有关,先注册的拦截器先执行。多个拦截器可以形成一个拦截器链,请求首先经过第一个拦截器的preHandle方法,如果该方法返回true,则继续向下执行,依次经过其他拦截器的preHandle方法,直到到达目标处理器。在处理器处理完请求后,会按照相反的顺序依次经过各个拦截器的postHandle和afterCompletion方法。

6-trigger-timing

一个请求的执行顺序是:请求进入容器 > 进入过滤器 > 进入 Servlet > 进入拦截器 > 执行控制器(Controller)。所以过滤器和拦截器的触发时机也是不同的,过滤器会先执行,然后才会执行拦截器,最后才会进入真正的要调用的方法。

3、实现不同

过滤器:

  • 实现了javax.servlet.Filter接口,并在doFilter方法中编写过滤逻辑。

  • 需要在 web.xml 文件中进行配置,或者使用注解(如果容器支持)进行配置。

 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
 import javax.servlet.ServletException;
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.annotation.WebFilter;
 import java.io.IOException;
 ​
 @WebFilter(filterName = "MyFilter", urlPatterns = "/*")
 public class MyFilter implements Filter {
 ​
     @Override
     public void init(FilterConfig filterConfig) throws ServletException {
         // 过滤器初始化时执行的操作
     }
 ​
     @Override
     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
         // 过滤前的操作
         System.out.println("Filter: Before request processing");
         filterChain.doFilter(servletRequest, servletResponse);
         // 过滤后的操作
         System.out.println("Filter: After request processing");
     }
 ​
     @Override
     public void destroy() {
         // 过滤器销毁时执行的操作
     }
 }

拦截器:

  • 通过实现org.springframework.web.servlet.HandlerInterceptor接口来创建拦截器,并实现其中的preHandle、postHandle和afterCompletion方法。

  • 在 Spring 配置文件中或者使用 Java 配置类进行配置。

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 在请求处理之前执行的操作
        System.out.println("Interceptor: Before request processing");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 在请求处理之后,视图渲染之前执行的操作
        System.out.println("Interceptor: After request processing but before view rendering");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 在整个请求完成后执行的操作,无论请求是否成功
        System.out.println("Interceptor: After request completion");
    }
}

4、作用范围不同

过滤器作用范围: 过滤器可以作用于所有的 Servlet 和 JSP,以及静态资源文件(如 HTML、CSS、JavaScript 文件等)。它可以对请求和响应的内容进行修改,例如对请求参数进行过滤、对响应内容进行压缩等。

拦截器作用范围: 拦截器主要作用于 Spring MVC 框架中的控制器方法。它可以对请求进行预处理和后处理,但不能直接修改请求和响应的内容。拦截器通常用于实现一些与业务逻辑相关的功能,如用户认证、权限检查等。

5、使用场景不同

过滤器使用场景:

  • 统一字符编码设置:确保所有的请求和响应都使用统一的字符编码,避免出现乱码问题。

  • 日志记录:记录请求的详细信息,如请求 URL、请求参数、响应状态码等,以便进行系统监控和故障排查。

  • 权限验证:对请求进行权限验证,例如检查用户是否具有访问特定资源的权限。如果用户没有权限,则可以直接返回错误响应,而无需将请求传递给目标资源。

  • 数据压缩:对响应内容进行压缩,减少网络传输的数据量,提高系统性能。

拦截器使用场景:

  • 用户登录验证:在用户请求到达控制器方法之前,检查用户是否已经登录。如果用户未登录,则可以重定向到登录页面或者返回错误响应。

  • 性能监控:记录请求的处理时间,以便进行系统性能分析和优化。

  • 事务管理:在控制器方法执行前后开启和关闭事务,确保数据库操作的原子性和一致性。

  • 日志记录:记录控制器方法的执行情况,如方法名称、参数值、返回值等,以便进行业务逻辑的监控和分析。

谦学于心,谷纳万物,静思致远,共筑收获之旅!

原文地址: https://www.emanjusaka.top/2024/09/filter-interceptor-difference

微信公众号:emanjusaka的编程栈

本篇完