SpringBoot实现拦截器的完整指南
SpringBoot 拦截器基于 Spring MVC Interceptor,用于请求前置/后置处理、登录校验、权限控制、日志记录等,下面分基础实现、多拦截器、常见配置一步步讲解。
一、核心流程
- 自定义拦截器类,实现
HandlerInterceptor接口 - 创建 Web 配置类,实现
WebMvcConfigurer注册拦截器 - 配置拦截路径、放行路径
- 测试验证
二、版本环境
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 "首页内容";
}
}
六、测试效果
- 访问
http://localhost:8080/index- 未登录 → 被拦截,重定向到
/login
- 未登录 → 被拦截,重定向到
- 先访问
http://localhost:8080/login(登录) - 再次访问
/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.servlet → jakarta.servlet):
// SpringBoot3 导入包 import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse;
其余逻辑、注册方式完全不变。
到此这篇关于SpringBoot实现拦截器的完整指南的文章就介绍到这了,更多相关SpringBoot拦截器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
java中double转化为BigDecimal精度缺失的实例
下面小编就为大家带来一篇java中double转化为BigDecimal精度缺失的实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧2017-03-03
搭建Springboot框架并添加JPA和Gradle组件的方法
这篇文章主要介绍了搭建Springboot框架并添加JPA和Gradle组件的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧2018-07-07
springboot jpa实现优雅处理isDelete的默认值
如果多个实体类都有 isDelete 字段,并且你希望在插入时为它们统一设置默认值时改怎么做呢,本文为大家整理了一些方法,希望对大家有所帮助2024-11-11


最新评论