java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > springboot拦截器和过滤器区别

springboot中的拦截器和过滤器的作用、区别解析

作者:bindabin

这篇文章主要介绍了springboot中的拦截器和过滤器的作用、区别解析,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

一、作用

1. 过滤器 (Filter)

2. 拦截器 (Interceptor)

二、执行顺序与位置(核心区别)

这是理解两者区别最直观的方式。一个 HTTP 请求的处理流程如下:

HTTP Request -> Tomcat -> Filter -> DispatcherServlet -> Interceptor -> Controller -> Interceptor -> Filter -> HTTP Response

  1. 请求到达:HTTP 请求首先被 Tomcat 等 Servlet 容器接收。
  2. 过滤器 (Filter):请求会依次经过配置的过滤器链(Filter Chain)。在这里,过滤器可以对请求进行“预处理”。
  3. 进入 Spring:请求通过过滤器后,到达 Spring MVC 的核心——DispatcherServlet
  4. 拦截器 (Interceptor)DispatcherServlet 会根据请求路径找到对应的 Handler(即Controller方法),但在执行之前,会先经过配置的拦截器链(Interceptor Chain)的 preHandle 方法。
  5. 执行控制器:如果所有拦截器的 preHandle 都返回 true,则执行真正的 Controller 方法。
  6. 后处理:Controller 方法执行完毕后,会依次经过拦截器链的 postHandle 方法(视图渲染前)。
  7. 视图渲染:进行视图渲染(如果是 MVC 模式)。
  8. 最终处理:视图渲染完成后(或完成后),会执行拦截器链的 afterCompletion 方法(请求完成后,可用于资源清理)。
  9. 返回响应:处理后的响应再次经过过滤器链,过滤器可以对响应进行“后处理”。
  10. 响应返回:最终,响应通过 Tomcat 返回给客户端。

简单比喻

三、区别与联系总结

特性过滤器 (Filter)拦截器 (Interceptor)
归属规范/框架Servlet 规范 (javax.servlet)Spring MVC 框架 (org.springframework.web.servlet)
依赖关系不依赖 Spring 容器,在 Web 服务器中运行强烈依赖 Spring 容器,可以调用 Spring 中的任何 Bean(如 Service)
作用范围作用于所有请求(包括静态资源,如 /css/, /js/只作用于进入 Spring MVC 控制器的请求(通常由 DispatcherServlet 处理)
获取 Bean无法直接注入 Spring Bean,需要通过其他方式(如 Spring 工具类)可以方便地使用 @Autowired 注入 Spring Bean
实现方式实现 javax.servlet.Filter 接口,重写 doFilter 方法实现 HandlerInterceptor 接口,重写 preHandle, postHandle, afterCompletion
控制粒度较粗,基于 ServletRequest 和 ServletResponse较细,可以获取到处理请求的控制器方法(HandlerMethod) 等信息
执行时机在 Servlet 之前和之后执行在 Controller 方法之前、之后、以及视图渲染完成后执行
异常处理在过滤器中发生的异常,可以在过滤链中进行处理在拦截器中发生的异常,可以被 Spring 的全局异常处理器(@ControllerAdvice)捕获

联系

  1. 功能相似:两者都实现了“横切关注点”的功能,用于实现与业务逻辑无关的通用功能(如日志、安全)。
  2. 执行顺序协作:它们在同一次请求处理流程中协同工作,过滤器在外层,拦截器在内层。

四、代码示例

1. 过滤器 (Filter) 示例

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
// 使用注解注册过滤器,并指定过滤的 URL 模式
@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        long startTime = System.currentTimeMillis();
        System.out.println("Filter: 请求预处理 - 设置字符编码");
        // 设置请求和响应编码
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        // 继续执行过滤器链,最终会到达 Servlet
        chain.doFilter(request, response);
        // 响应后处理
        long endTime = System.currentTimeMillis();
        System.out.println("Filter: 响应后处理 - 请求耗时: " + (endTime - startTime) + "ms");
    }
    // ... 其他 init 和 destroy 方法
}

注意:在 Spring Boot 中,通常使用 @Component 或配置类来注册 Filter,@WebFilter 有时需要与 @ServletComponentScan 配合使用。

2. 拦截器 (Interceptor) 示例

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("Interceptor: preHandle - 在控制器方法执行之前");
        // 登录校验逻辑
        // if (!isLogin(request)) {
        //     response.sendRedirect("/login");
        //     return false; // 中断执行,不会到达 Controller
        // }
        System.out.println("用户已登录,放行");
        return true; // 继续执行,到达 Controller
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("Interceptor: postHandle - 控制器方法执行完毕,视图渲染之前");
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("Interceptor: afterCompletion - 整个请求已完成,视图已渲染");
        // 资源清理等工作
    }
}

还需要一个配置类来注册拦截器并指定拦截路径:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private MyInterceptor myInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor)
                .addPathPatterns("/api/**") // 拦截所有 /api 开头的路径
                .excludePathPatterns("/api/login"); // 排除登录接口
    }
}

五、如何选择?

在大多数基于 Spring Boot 的业务开发中,拦截器是更常用和更强大的选择,尤其是处理权限、日志等业务相关切面。

到此这篇关于java springboot中的拦截器和过滤器的作用、区别和联系的文章就介绍到这了,更多相关springboot拦截器和过滤器区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文