SpringBoot实现拦截器的完整指南

 更新时间:2026年06月12日 09:00:21   作者:码不停蹄的玄黓  
SpringBoot拦截器基于 Spring MVC Interceptor,用于请求前置/后置处理、登录校验、权限控制、日志记录等,本文详细介绍了SpringBoot拦截器的基础实现,多拦截器实现和常见配置,有需要的小伙伴可以参考下

SpringBoot 拦截器基于 Spring MVC Interceptor,用于请求前置/后置处理、登录校验、权限控制、日志记录等,下面分基础实现多拦截器常见配置一步步讲解。

一、核心流程

  1. 自定义拦截器类,实现 HandlerInterceptor 接口
  2. 创建 Web 配置类,实现 WebMvcConfigurer 注册拦截器
  3. 配置拦截路径、放行路径
  4. 测试验证

二、版本环境

SpringBoot 2.x / 3.x 通用写法(SpringBoot3 仅依赖包无变化)

依赖(常规Web项目即可)

<!-- pom.xml -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

三、第一步:自定义拦截器

实现 HandlerInterceptor,包含 3 个核心方法:

  • preHandle:控制器执行之前执行,返回 true 放行,false 拦截
  • postHandle:控制器执行后、视图渲染前执行
  • afterCompletion:请求完全结束(视图渲染完毕)后执行,多用于资源释放
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

/**
 * 自定义登录拦截器
 */
public class LoginInterceptor implements HandlerInterceptor {

    private static final Logger log = LoggerFactory.getLogger(LoginInterceptor.class);

    // 控制器执行前
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("【拦截器】请求进入 preHandle,地址:{}", request.getRequestURI());

        // 示例:登录校验(从session获取登录用户)
        Object user = request.getSession().getAttribute("loginUser");
        if (user == null) {
            log.info("【拦截器】未登录,拦截请求");
            // 重定向到登录页 / 前后端分离则返回JSON
            response.sendRedirect("/login");
            return false; // 拦截请求
        }
        return true; // 放行
    }

    // 控制器执行后,视图渲染前
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("【拦截器】执行 postHandle");
    }

    // 整个请求完成后(最后执行)
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("【拦截器】请求结束 afterCompletion");
    }
}

四、第二步:注册拦截器(核心配置)

新建配置类,实现 WebMvcConfigurer,重写 addInterceptors 方法注册拦截器。

关键配置说明

  • addPathPatterns()要拦截的路径
    • /** 拦截所有请求
    • /api/** 拦截 api 下所有接口
  • excludePathPatterns()放行路径(登录、静态资源、验证码等)
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * Web 全局配置类,注册拦截器
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                // 1. 拦截所有请求
                .addPathPatterns("/**")
                // 2. 放行路径:登录接口、静态资源、首页等
                .excludePathPatterns("/login")
                .excludePathPatterns("/static/**")
                .excludePathPatterns("/error"); // 放行全局异常页
    }
}

注意:不要加 @EnableWebMvc,加了会覆盖 SpringBoot 默认 Web 配置,导致静态资源、日期格式化等失效。

五、第三步:编写测试接口/页面

登录控制器(模拟登录)

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;

@RestController
public class TestController {

    // 登录接口(放行)
    @GetMapping("/login")
    public String login(HttpSession session) {
        // 模拟登录成功,存入session
        session.setAttribute("loginUser", "admin");
        return "登录成功";
    }

    // 需拦截的接口
    @GetMapping("/index")
    public String index() {
        return "首页内容";
    }
}

六、测试效果

  1. 访问 http://localhost:8080/index
    • 未登录 → 被拦截,重定向到 /login
  2. 先访问 http://localhost:8080/login(登录)
  3. 再次访问 /index → 正常放行,控制台打印拦截器日志

七、进阶用法

1. 多个拦截器(执行顺序)

注册多个拦截器,先注册先执行(preHandle 顺序:注册顺序;afterCompletion 逆序)

@Override
public void addInterceptors(InterceptorRegistry registry) {
    // 拦截器1 先执行
    registry.addInterceptor(new Interceptor1()).addPathPatterns("/**");
    // 拦截器2 后执行
    registry.addInterceptor(new Interceptor2()).addPathPatterns("/**");
}

2. 前后端分离场景(返回JSON而非重定向)

替换 preHandle 中未登录逻辑,返回 JSON 提示:

if (user == null) {
    response.setContentType("application/json;charset=utf-8");
    response.getWriter().write("{\"code\":401,\"msg\":\"请先登录\"}");
    return false;
}

3. 排除静态资源

SpringBoot 默认静态资源目录:/static/public/resources/META-INF/resources

统一放行:

.excludePathPatterns("/static/**", "/public/**")

4. 拦截指定 Controller/接口

只拦截 /api/user/** 下接口:

.addPathPatterns("/api/user/**")

八、常见问题

拦截器不生效

  • 检查配置类是否加 @Configuration
  • 确认没写 @EnableWebMvc
  • 路径匹配是否正确(/**/* 区别:/* 只拦截一级路径)

404 页面被拦截

手动放行 /error 路径

拦截器无法获取 @RequestBody 参数

原因:流只能读取一次,需配合 请求体包装器 解决。

补充:SpringBoot3 额外说明

SpringBoot3 基于 Spring6,API 完全兼容以上代码,仅部分包路径变化(javax.servletjakarta.servlet):

// SpringBoot3 导入包
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

其余逻辑、注册方式完全不变。

到此这篇关于SpringBoot实现拦截器的完整指南的文章就介绍到这了,更多相关SpringBoot拦截器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java中double转化为BigDecimal精度缺失的实例

    java中double转化为BigDecimal精度缺失的实例

    下面小编就为大家带来一篇java中double转化为BigDecimal精度缺失的实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • springboot结合JWT实现单点登录的示例

    springboot结合JWT实现单点登录的示例

    本文主要介绍了springboot结合JWT实现单点登录的示例,包括生成Token、验证Token及使用Redis存储Token,具有一定的参考价值,感兴趣的可以了解一下
    2025-01-01
  • JAVA基础之注解与反射的使用方法和场景

    JAVA基础之注解与反射的使用方法和场景

    这篇文章主要给大家介绍了关于JAVA基础之注解与反射的使用方法和场景的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • SpringBoot中缓存注解的使用详解

    SpringBoot中缓存注解的使用详解

    为了实现缓存,Spring Boot 提供了一些缓存注解,可以方便地实现缓存功能,这篇文章主要介绍了SpringBoot中常用的缓存注解的使用方法,需要的可以参考一下
    2023-06-06
  • Java正则匹配中文的方法实例分析

    Java正则匹配中文的方法实例分析

    这篇文章主要介绍了Java正则匹配中文的方法,结合实例形式分析了Java针对中文、标点及引号等匹配操作相关技巧,需要的朋友可以参考下
    2017-03-03
  • 搭建Springboot框架并添加JPA和Gradle组件的方法

    搭建Springboot框架并添加JPA和Gradle组件的方法

    这篇文章主要介绍了搭建Springboot框架并添加JPA和Gradle组件的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-07-07
  • JAVA transient 关键字作用详解

    JAVA transient 关键字作用详解

    Java的transient关键字用于修饰成员变量,使其不参与序列化过程,通过自定义序列化方法,可以手动控制transient变量的序列化行为,本文给大家介绍JAVA transient 关键字作用,感兴趣的朋友跟随小编一起看看吧
    2025-11-11
  • mybatis-plus分表实现案例(附示例代码)

    mybatis-plus分表实现案例(附示例代码)

    MyBatis-Plus是一个MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生,这篇文章主要介绍了mybatis-plus分表实现的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-12-12
  • 两个List集合取相同重复数据的方法

    两个List集合取相同重复数据的方法

    今天小编就为大家分享一篇关于两个List集合取相同重复数据的方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • springboot jpa实现优雅处理isDelete的默认值

    springboot jpa实现优雅处理isDelete的默认值

    如果多个实体类都有 isDelete 字段,并且你希望在插入时为它们统一设置默认值时改怎么做呢,本文为大家整理了一些方法,希望对大家有所帮助
    2024-11-11

最新评论