Bootstrap

过滤器filter)和拦截器Interceptor的区别以及使用场景

二者区别:

1. 实现原理不同
过滤器和拦截器 底层实现方式不相同,过滤器是基于函数回调的,拦截器则是基于Java的反射机制(动态代理)实现的。

2. 使用范围不同
过滤器实现的是 javax.servlet.Filter 接口,而这个接口是在Servlet规范中定义的,也就是说过滤器Filter 的使用要依赖于Tomcat等容器,导致它只能在web程序中使用。

而拦截器是一个Spring组件,并由Spring容器管理,并不依赖Tomcat等容器,是可以单独使用的。不仅能应用在web程序中,也可以用于Application、Swing等程序中。

3. 触发时机不同
过滤器 和 拦截器的触发时机不同。

如上图所示,过滤器Filter是在请求进入容器后,但在进入servlet之前进行预处理,请求结束是在servlet处理完以后。

拦截器 Interceptor 是在请求进入servlet后,在进入Controller之前进行预处理的,Controller 中渲染了对应的视图之后请求结束。

4. 拦截的请求范围不同
Filter对所有访问进行增强,Interceptor仅针对SpringMVC的访问进行增强。

具体说明:

在 Java Web 开发中,拦截器(Interceptor)和过滤器(Filter)是两种常用的机制,用于拦截和处理 HTTP 请求和响应。虽然它们在某些场景下可以实现类似的功能,但它们的用途、工作方式和生命周期有所不同。

拦截器(Interceptor)

主要特点

  1. 工作原理:拦截器是 Spring 框架的一部分,通常用于拦截 Controller 层的请求。它通过 AOP(面向切面编程)思想,允许在方法调用前后或异常发生时执行自定义逻辑。
  2. 应用场景:常用于身份验证、权限检查、日志记录等操作,具体到控制器层面。
  3. 执行顺序:可以配置多个拦截器,并通过 preHandlepostHandleafterCompletion 方法实现不同阶段的处理。
public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 在请求处理之前调用(Controller方法调用之前)
        System.out.println("Pre Handle method is called");
        return true; // 返回 true 表示继续处理请求,返回 false 表示中止请求
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 在请求处理之后调用(Controller方法调用之后)
        System.out.println("Post Handle method is called");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 在整个请求完成之后调用(通常用于资源清理)
        System.out.println("Request and Response is completed");
    }
}

配置拦截器

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor())
                .addPathPatterns("/api/**") // 拦截所有 /api/** 路径的请求
                .excludePathPatterns("/api/login"); // 排除特定路径
    }
}

过滤器(Filter)

主要特点

  1. 工作原理:过滤器是 Servlet 规范的一部分,作用于 Servlet 容器中,通常用于在请求到达 Servlet 之前和响应返回客户端之前进行预处理或后处理。
  2. 应用场景:常用于通用任务,如日志记录、身份验证、字符编码设置、跨域处理、请求和响应的修改等。
  3. 执行顺序:可以通过 doFilter 方法对请求和响应进行处理,多个过滤器按照配置的顺序依次执行。

示例

public class MyFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 过滤器初始化
        System.out.println("Filter initialized");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        // 在请求处理前执行
        System.out.println("Request is being filtered");
        
        // 继续执行后续过滤器或目标资源(如Servlet)
        chain.doFilter(request, response);
        
        // 在响应处理后执行
        System.out.println("Response is being filtered");
    }

    @Override
    public void destroy() {
        // 过滤器销毁
        System.out.println("Filter destroyed");
    }
}

配置过滤器

  • 通过 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>/api/*</url-pattern>
</filter-mapping>
  • 通过 Spring Boot 配置
@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean<MyFilter> loggingFilter() {
        FilterRegistrationBean<MyFilter> registrationBean = new FilterRegistrationBean<>();
        
        registrationBean.setFilter(new MyFilter());
        registrationBean.addUrlPatterns("/api/*"); // 过滤 /api/* 路径的请求
        
        return registrationBean;
    }
}

拦截器和过滤器的区别

  1. 作用范围

    • 拦截器:作用于 Spring MVC 的控制器层面,能够访问控制器处理的方法和返回的模型数据。
    • 过滤器:作用于整个 Servlet 容器,可以处理所有进入的请求(包括静态资源),在请求达到控制器之前进行拦截。
  2. 生命周期

    • 拦截器:由 Spring 容器管理,通常在请求进入 Controller 之前、之后和整个请求完成之后执行。
    • 过滤器:由 Servlet 容器管理,生命周期与应用程序一起开始和结束,在请求到达 Servlet 之前和响应返回客户端之前执行。
  3. 使用场景

    • 拦截器:更适合用于权限验证、业务逻辑预处理、请求日志记录等与业务相关的拦截操作。
    • 过滤器:更适合用于请求和响应的全局处理,如日志记录、请求编码设置、跨域处理等。
  4. 执行顺序

    • 拦截器:多个拦截器之间的执行顺序可以通过配置来控制,并且可以在请求前后分别执行。
    • 过滤器:多个过滤器之间按照配置的顺序依次执行。

通过理解这两者的差异,可以更好地选择和应用这两种机制来满足项目的具体需求。

;