Spring Boot拦截器Interceptor与过滤器Filter详细教程(示例详解)

本文主要是介绍Spring Boot拦截器Interceptor与过滤器Filter详细教程(示例详解),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《SpringBoot拦截器Interceptor与过滤器Filter详细教程(示例详解)》本文详细介绍了SpringBoot中的拦截器(Interceptor)和过滤器(Filter),包括它们的...

Spring Boot拦截器(Interceptor)与过滤器(Filter)详细教程

1. 概述

1.1 什么是拦截器(Interceptor)?

拦截器是 Spring MVC 框架的组件,基于 AOP(面向切面编程 实现。它允许在请求处理的不同阶段(如Controller方法执行前后)插入自定义逻辑。

1.2 什么是过滤器(Filter)?

过滤器是 Java Servlet规范 定义的组件,作用于所有进入容器的请求(如Tomcat)。它可以在请求到达Servlet前或响应返回客户端前进行预处理和后处理。

1.3 核心区别

特性拦截器(Interceptor)过滤器(Filter)
所属框架Spring MVCServlet API
作用范围仅Spring MVC管理的请求所有请求(包括静态资源)
依赖依赖Spring容器依赖Servlet容器(如Tomcat)
执行时机Controller方法前后Servlet处理前后
获取Bean支持(通过Spring上下文)不支持(需通过其他方式注入)

2. 使用场景

2.1 拦http://www.chinasem.cn截器的典型应用

  • 日志记录:记录请求参数、响应时间。
  • 权限验证:检查用户是否登录或拥有权限。
  • 事务管理:在Controller方法前后开启/提交事务。
  • 性能监控:统计接口耗时。

2.2 过滤器的典型应用

  • 全局字符编码:统一设置请求/响应的编码(如UTF-8)。
  • 跨域处理:添加CORS响应头。
  • XSS防御:过滤请求参数中的恶意脚本
  • 请求压缩:对响应内容进行GZIP压缩。

3. 实现步骤

3.1 创建拦截器

步骤:

实现 HandlerInterceptor 接口,重写以下方法:

  • preHandle():在Controller方法执行前调用。
  • postHandle():在Controller方法执行后、视图渲染前调用。
  • afterCompletion():在请求完成后调用(视图渲染后)。

注册拦截器到Spring MVC配置。

代码示例:

public class AuthInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 检查用户是否登录
        if (request.getSession().getAttribute("user") == null) {
            response.sendRedirect("/login");
            return false; // 中断请求
        }
        return true;
    }
}

注册拦截器:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new AuthInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/login", "/static/**");
    }
}

注册多个拦截器:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 第一个拦截器:日志(优先级高)
        registry.addInterceptor(new LogInterceptor())
                .addPathPatterns("/**")       // 拦截所有路径
                .excludePathPatterns("/static/**"); // 排除静态资源
        // 第二个拦截器:权限(优先级低)
        registry.addInterceptor(new AuthInterceptor())
                .addPathPatterns("/api/**");  // 仅拦截/api路径
    }
}

关键配置选项

配置方法说明
addPathPatterns("/api")指定拦截的路径(支持Ant风格)
excludePathPatterns("/login")排除特定路径
order(1)显式设置顺序(默认按注册顺序)

若要手动指定顺序,可添加:

registry.addInterceptor(new LogInterceptor()).order(1);
registry.addInterceptor(new AuthInterceptor()).order(2);

3.2 创建过滤器

步骤:

  • 实现 javax.servlet.Filter 接口,重写 doFilter 方法。
  • 注册过滤器到Servlet容器(通过注解或配置类)。

代码示例:

@WebFilter(urlPatterns = "/*")
public class LoggingFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
            throws IOException, ServletException {
        System.out.println("请求开始: " + ((HttpServletRequest) request).getRequestURI());
        chain.doFilter(request, response); // 继续执行后续过滤器或Servlet
        System.out.println("请求结束");
    }
}

注册过滤器(若未使用@WebFilter):

@ConfChina编程iguration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean<LoggingFilter> loggingFilter() {
        FilterRegistrationBean<LoggingFilter> bean = new FilterRegistrationBean<>();
        bean.setFilter(new LoggingFilter());
        bean.addUrlPatterns("/*");
        bean.setOrder(1); // 设置执行顺序
        return bean;
    }
}

注意: 确保主类添加 @ServletComponentScan 以启用 @WebFilter 注解。

4KwTWHYqR. 执行顺序与流程

4.1 执行顺序

  • 过滤器(FilterChain) → 2. 拦截器(preHandle) → 3. Controller方法 → 4. 拦截器(postHandle) → 5. 视图渲染 → 6. 拦截器(afterCompletion) → 7. 过滤器后续处理

4.2 流程图

客户端 → Filter.doFilter() → Interceptor.preHandle()
       → Controller → Interjsceptor.postHandle()
       → 视图渲染 → Interceptor.afterCompletion()
       → Filter.doFilter()后续处理 → 客户端

5. 常见问题与解决方案

Q1:如何控制多个拦截器/过滤器的执行顺序?

  • 拦截器:通过 registry.addInterceptor() 的顺序决定。
  • 过滤器:通过 FilterRegistrationBean.setOrder() 设置优先级(值越小越先执行)。

Q2:拦截器中如何获取Spring管理的Bean?

直接从Spring容器注入:

public class AuthInterceptor implements HandlerInterceptor {
    @Autowired
    private UserService userService; // 直接注入
}

Q3:过滤器中如何修改请求参数?

通过自定义 HttpServletRequestWrapper

public class ModifyRequestWrapper extends HttpServletRequestWrapper {
    // 重写getParameter等方法以修改参数
}
// 在Filter中替换Request对象
chain.doFilter(new ModifyRequestWrapper(request), response);

Q4:拦截器和过滤器执行时出现异常如何处理?

  • 拦截器:在 afterCompletion 中处理异常。
  • 过滤器:使用 try-catch 包裹 chain.doFilter()

Q5:如何让某个拦截器全局生效?

使用 addPathPatterns("/**")

registry.addInterceptor(new LogInterceptor())
        .addPathPatterns("/**");

Q6:如何跳过特定拦截器的执行?

preHandle 中返回 false

@Override
public boolean preHandle(...) {
    if (跳过条件) {
        return false; // 后续拦截器和Controller不会执行
    }
    return true;
}

Q7:拦截器之间如何共享数据?

通过 request.setAttribute 传递:

// 在第一个拦截器中存储数据
request.setAttribute("key", "value");
// 在后续拦截器中获取
String value = (String) request.getAttribute("key");

6. 总结

选择拦截器还是过滤器?

  • 需要访China编程问Spring上下文或Controller信息 → 拦截器。
  • 需处理所有请求(包括静态资源) → 过滤器。

最佳实践

  • 优先使用拦截器处理业务相关逻辑。
  • 使用过滤器处理底层Servlet容器的任务(如编码、压缩)。

到此这篇关于Spring Boot拦截器(Interceptor)与过滤器(Filter)详细教程的文章就介绍到这了,更多相关Spring Boot拦截器与过滤器内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持China编程(www.chinasem.cn)!

这篇关于Spring Boot拦截器Interceptor与过滤器Filter详细教程(示例详解)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1153798

相关文章

Java导入、导出excel用法步骤保姆级教程(附封装好的工具类)

《Java导入、导出excel用法步骤保姆级教程(附封装好的工具类)》:本文主要介绍Java导入、导出excel的相关资料,讲解了使用Java和ApachePOI库将数据导出为Excel文件,包括... 目录前言一、引入Apache POI依赖二、用法&步骤2.1 创建Excel的元素2.3 样式和字体2.

Java实现将Markdown转换为纯文本

《Java实现将Markdown转换为纯文本》这篇文章主要为大家详细介绍了两种在Java中实现Markdown转纯文本的主流方法,文中的示例代码讲解详细,大家可以根据需求选择适合的方案... 目录方法一:使用正则表达式(轻量级方案)方法二:使用 Flexmark-Java 库(专业方案)1. 添加依赖(Ma

C++快速排序超详细讲解

《C++快速排序超详细讲解》快速排序是一种高效的排序算法,通过分治法将数组划分为两部分,递归排序,直到整个数组有序,通过代码解析和示例,详细解释了快速排序的工作原理和实现过程,需要的朋友可以参考下... 目录一、快速排序原理二、快速排序标准代码三、代码解析四、使用while循环的快速排序1.代码代码1.由快

C语言字符函数和字符串函数示例详解

《C语言字符函数和字符串函数示例详解》本文详细介绍了C语言中字符分类函数、字符转换函数及字符串操作函数的使用方法,并通过示例代码展示了如何实现这些功能,通过这些内容,读者可以深入理解并掌握C语言中的字... 目录一、字符分类函数二、字符转换函数三、strlen的使用和模拟实现3.1strlen函数3.2st

Go语言中最便捷的http请求包resty的使用详解

《Go语言中最便捷的http请求包resty的使用详解》go语言虽然自身就有net/http包,但是说实话用起来没那么好用,resty包是go语言中一个非常受欢迎的http请求处理包,下面我们一起来学... 目录安装一、一个简单的get二、带查询参数三、设置请求头、body四、设置表单数据五、处理响应六、超

SpringBoot利用dynamic-datasource-spring-boot-starter解决多数据源问题

《SpringBoot利用dynamic-datasource-spring-boot-starter解决多数据源问题》dynamic-datasource-spring-boot-starter是一... 目录概要整体架构构想操作步骤创建数据源切换数据源后续问题小结概要自己闲暇时间想实现一个多租户平台,

详解如何使用Python提取视频文件中的音频

《详解如何使用Python提取视频文件中的音频》在多媒体处理中,有时我们需要从视频文件中提取音频,本文为大家整理了几种使用Python编程语言提取视频文件中的音频的方法,大家可以根据需要进行选择... 目录引言代码部分方法扩展引言在多媒体处理中,有时我们需要从视频文件中提取音频,以便进一步处理或分析。本文

mybatis-plus 实现查询表名动态修改的示例代码

《mybatis-plus实现查询表名动态修改的示例代码》通过MyBatis-Plus实现表名的动态替换,根据配置或入参选择不同的表,本文主要介绍了mybatis-plus实现查询表名动态修改的示... 目录实现数据库初始化依赖包配置读取类设置 myBATis-plus 插件测试通过 mybatis-plu

Java反转字符串的五种方法总结

《Java反转字符串的五种方法总结》:本文主要介绍五种在Java中反转字符串的方法,包括使用StringBuilder的reverse()方法、字符数组、自定义StringBuilder方法、直接... 目录前言方法一:使用StringBuilder的reverse()方法方法二:使用字符数组方法三:使用自

使用Dify访问mysql数据库详细代码示例

《使用Dify访问mysql数据库详细代码示例》:本文主要介绍使用Dify访问mysql数据库的相关资料,并详细讲解了如何在本地搭建数据库访问服务,使用ngrok暴露到公网,并创建知识库、数据库访... 1、在本地搭建数据库访问的服务,并使用ngrok暴露到公网。#sql_tools.pyfrom