Filter与Interceptor的选择困难症

在实际的项目开发过程中,我们经常会遇到Filter与Interceptor,这两者更是面试过程中经常问到的一个点,恰恰因为这两者的使用以及他们的作用都颇为的相似,很多人回答的模凌两可,甚至在用的时候也不能该如何去选型。今天通过这篇文章,我们就来彻底的分析分析,这二者到底有什么区别。

Filter(过滤器)

概述

Servlet规范中定义的一种组件,用于在请求进入Servlet之前或响应返回客户端之前执行一些操作。它依赖于Servlet容器,几乎可以对任何请求进行过滤,随着Web应用的启动而启动,Web应用停止则Filter销毁。

工作原理

通过实现javax.servlet.Filter,对请求进行过滤拦截,进而做统一处理。最后将请求交给Servlet进行处理并生成得到响应。得到响应以后,Filter可以对响应再次进行处理。

应用场景

如进行过滤低俗文字,危险字符,日志记录、权限验证、字符编码处理等等。如防XSS攻击的XSSFilter过滤器。

代码实现(SpringBoot举例)

创建Filter类

java 复制代码
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() {
        // 销毁操作
    }
}

注册Filter

在Spring Boot中,我们可以通过配置类或使用@WebFilter注解来注册Filter。

java 复制代码
@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean<MyFilter> myFilter() {
        FilterRegistrationBean<MyFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new MyFilter());
        registrationBean.addUrlPatterns("/api/*"); // 设置过滤的路径
        return registrationBean;
    }
}

Interceptor 拦截器介绍

概述

Interceptor是Spring框架提供的一种拦截器,与Servlet无关,它依赖于Web框架,用于在Controller方法执行前后进行处理。与Filter不同,Interceptor是Spring MVC框架特有的组件。它可以将一些共有的行为动作给通用化、标准化,进而让代码更加简洁,可扩展性更高。

原理

基于实现HandlerInterceptor接口,并重写它的方法。 它有如下方法:

  • preHandle方法:目标资源方法执行前执行。 返回true则继续往下执行 返回false则进行拦截。
  • postHandle方法:目标资源方法执行后执行
  • afterCompletion方法:视图渲染完毕后执行,最后执行。

应用场景

Interceptor主要用于处理与Controller相关的逻辑,比如权限验证、日志记录、统一异常处理等。

代码实现

创建Interceptor类

java 复制代码
public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        // 在Controller方法执行前执行的操作
        // 返回true表示继续执行,返回false表示中断执行
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
        // 在Controller方法执行后、视图渲染前执行的操作
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
                                Exception ex) throws Exception {
        // 在整个请求完成后执行的操作
    }
}

注册Interceptor

java 复制代码
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 InterceptorConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor())
                .addPathPatterns("/api/**") // 设置拦截的路径
                .excludePathPatterns("/api/public/**"); // 设置排除的路径
    }
}

Filter与Interceptor的区别及如何选择

执行时机不同

  • Filter:在请求进入Servlet之前和响应返回客户端之前执行。
  • Interceptor:在Controller方法执行前、执行后、视图渲染前以及整个请求完成后执行。

范围

  • Filter:作用于整个Web应用,不仅限于Spring MVC。
  • Interceptor:仅作用于Spring MVC中的Controller层。

使用场景

  • Filter:适用于通用的请求处理逻辑,比如字符编码、日志记录等。
  • Interceptor:适用于与Controller相关的业务逻辑,比如权限验证、统一异常处理等。

选择使用Filter还是Interceptor取决于具体的需求,通常可以根据业务逻辑的不同来灵活运用它们。

总的来说,Filter和Interceptor都是在请求处理过程中执行一些操作的良好扩展点,可以帮助我们更好地管理和控制Web应用的行为。在实际项目中,根据具体的需求和场景,选择合适的组件来实现定制化的处理逻辑。

相关推荐
码蜂窝编程官方10 分钟前
【含开题报告+文档+PPT+源码】基于SpringBoot+Vue的虎鲸旅游攻略网的设计与实现
java·vue.js·spring boot·后端·spring·旅游
hummhumm28 分钟前
第 25 章 - Golang 项目结构
java·开发语言·前端·后端·python·elasticsearch·golang
J老熊38 分钟前
JavaFX:简介、使用场景、常见问题及对比其他框架分析
java·开发语言·后端·面试·系统架构·软件工程
AuroraI'ncoding1 小时前
时间请求参数、响应
java·后端·spring
好奇的菜鸟1 小时前
Go语言中的引用类型:指针与传递机制
开发语言·后端·golang
Alive~o.01 小时前
Go语言进阶&依赖管理
开发语言·后端·golang
许苑向上1 小时前
Dubbo集成SpringBoot实现远程服务调用
spring boot·后端·dubbo
郑祎亦2 小时前
Spring Boot 项目 myblog 整理
spring boot·后端·java-ee·maven·mybatis
本当迷ya2 小时前
💖2025年不会Stream流被同事排挤了┭┮﹏┭┮(强烈建议实操)
后端·程序员
计算机毕设指导63 小时前
基于 SpringBoot 的作业管理系统【附源码】
java·vue.js·spring boot·后端·mysql·spring·intellij-idea