
文章目录
- [SpringBoot4.0 拦截器-监听器实战](#SpringBoot4.0 拦截器-监听器实战)
SpringBoot4.0 拦截器-监听器实战
拦截器的概念和作用
核心概念说明
- 拦截器(Interceptor)是Spring MVC框架中的重要组件;
- 用于在请求处理的前后添加预处理和后处理逻辑;
- 类似于Servlet中的Filter,但功能更强大,可以获取Spring容器中的Bean。
拦截器与过滤器对比
| 特性 | 拦截器(Interceptor) | 过滤器(Filter) |
|---|---|---|
| 依赖框架 | Spring MVC | Servlet规范 |
| 作用范围 | 控制器方法级别 | 请求级别 |
| 获取Bean | 可以获取Spring Bean | 不能直接获取 |
| 执行时机 | 控制器方法执行前后 | 请求进入Servlet前后 |
| 配置方式 | 实现HandlerInterceptor | web.xml或@WebFilter |
拦截器的执行流程:
请求 → 过滤器 → 拦截器preHandle → 控制器 → 拦截器postHandle → 视图渲染 → 拦截器afterCompletion → 响应
拦截器实战
创建拦截器步骤
- 实现HandlerInterceptor接口
- 重写三个核心方法
- 配置拦截器注册
登录验证拦截器
java
@Component
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("=== 进入拦截器 ===");
log.info("请求URL: " + request.getRequestURI());
log.info("请求方法: " + request.getMethod());
// 登录验证逻辑
HttpSession session = request.getSession();
Object user = session.getAttribute("user");
if (user == null) {
// 未登录,返回错误信息
response.setContentType("application/json;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.write("{\"code\": 401, \"message\": \"请先登录\"}");
writer.flush();
return false; // 中断请求
}
return true; // 继续执行
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
log.info("=== 控制器执行完成 ===");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
log.info("=== 请求处理完成 ===");
if (ex != null) {
log.info("异常信息: " + ex.getMessage());
}
}
}
配置拦截器注册
java
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private LoginInterceptor loginInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor)
.addPathPatterns("/**") // 拦截所有路径
.excludePathPatterns( // 排除路径
"/user/login",
"/user/register",
"/css/**",
"/js/**",
"/images/**"
);
}
}
测试结果
sh
2026-01-18T21:25:46.606+08:00 INFO 21940 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2026-01-18T21:25:46.606+08:00 INFO 21940 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2026-01-18T21:25:46.606+08:00 INFO 21940 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 0 ms
2026-01-18T21:25:46.616+08:00 INFO 21940 --- [nio-8080-exec-1] c.g.interceptor.LoginInterceptor : === 进入拦截器 ===
2026-01-18T21:25:46.616+08:00 INFO 21940 --- [nio-8080-exec-1] c.g.interceptor.LoginInterceptor : 请求URL: /user/info
2026-01-18T21:25:46.616+08:00 INFO 21940 --- [nio-8080-exec-1] c.g.interceptor.LoginInterceptor : 请求方法: GET
2026-01-18T21:25:53.584+08:00 INFO 21940 --- [nio-8080-exec-3] c.g.interceptor.LoginInterceptor : === 进入拦截器 ===
2026-01-18T21:25:53.584+08:00 INFO 21940 --- [nio-8080-exec-3] c.g.interceptor.LoginInterceptor : 请求URL: /user/info
2026-01-18T21:25:53.584+08:00 INFO 21940 --- [nio-8080-exec-3] c.g.interceptor.LoginInterceptor : 请求方法: GET
2026-01-18T21:25:53.586+08:00 INFO 21940 --- [nio-8080-exec-3] c.g.interceptor.LoginInterceptor : === 控制器执行完成 ===
2026-01-18T21:25:53.586+08:00 INFO 21940 --- [nio-8080-exec-3] c.g.interceptor.LoginInterceptor : === 请求处理完成 ===
监听器概念和作用**
核心概念说明
- 监听器(Listener)用于监听Web应用中的事件
- 可以监听ServletContext、HttpSession、ServletRequest的生命周期事件
- 在特定事件发生时执行相应的业务逻辑
监听器类型分类
| 监听器类型 | 监听事件 | 应用场景 |
|---|---|---|
| ServletContextListener | 应用启动和关闭 | 初始化资源、加载配置 |
| ServletContextAttributeListener | 应用域属性变化 | 监控配置变化 |
| HttpSessionListener | Session创建和销毁 | 在线用户统计 |
| HttpSessionAttributeListener | Session属性变化 | 用户状态跟踪 |
| ServletRequestListener | 请求开始和结束 | 请求统计、日志记录 |
监听器执行时机
应用启动 → Context初始化 → 监听器contextInitialized → 请求到达 → Session创建 → 监听器sessionCreated
监听器实战
java
@Component
public class SessionListener implements HttpSessionListener {
private static final Logger logger = LoggerFactory.getLogger(SessionListener.class);
private static final AtomicInteger onlineUserCount = new AtomicInteger(0);
/**
* Session创建时调用
*/
@Override
public void sessionCreated(HttpSessionEvent se) {
int count = onlineUserCount.incrementAndGet();
logger.info("新用户登录,当前在线用户数: {}", count);
// 设置Session超时时间(30分钟)
se.getSession().setMaxInactiveInterval(30 * 60);
}
/**
* Session销毁时调用
*/
@Override
public void sessionDestroyed(HttpSessionEvent se) {
int count = onlineUserCount.decrementAndGet();
logger.info("用户退出,当前在线用户数: {}", count);
}
/**
* 获取当前在线用户数
*/
public static int getOnlineUserCount() {
return onlineUserCount.get();
}
}
java
@GetMapping("/hello")
public String hello(HttpSession session) {
return "在线人数:"+ SessionListener.getOnlineUserCount();
}
自动注册说明
- SpringBoot4.0自动扫描@Component注解的监听器;
- 无需额外配置,自动注册到Servlet容器;
- 支持同时注册多个监听器,按需执行。