第6章:SpringBoot 拦截器-监听器实战

文章目录

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 → 响应

拦截器实战

创建拦截器步骤

  1. 实现HandlerInterceptor接口
  2. 重写三个核心方法
  3. 配置拦截器注册

登录验证拦截器

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容器;
  • 支持同时注册多个监听器,按需执行。
相关推荐
alonewolf_993 小时前
RabbitMQ应用开发实战:从基础编程到SpringBoot集成全面指南
spring boot·消息队列·rabbitmq·java-rabbitmq
子非鱼9214 小时前
MyBatisPlus快速上手
数据库·spring boot·mybatisplus
皙然4 小时前
SpringBoot 自动装配深度解析:从底层原理到自定义 starter 实战(含源码断点调试)
java·spring boot·spring
J_liaty6 小时前
RocketMQ快速入门与Spring Boot整合实践
spring boot·rocketmq·java-rocketmq
小北方城市网6 小时前
SpringBoot 集成 RabbitMQ 实战(消息队列):实现异步通信与系统解耦
java·spring boot·后端·spring·rabbitmq·mybatis·java-rabbitmq
indexsunny7 小时前
互联网大厂Java面试实战:Spring Boot与微服务在电商场景中的应用解析
java·数据库·spring boot·微服务·maven·flyway·电商
sunnyday04267 小时前
从混乱到清晰:Maven 依赖版本管理最佳实践
java·spring boot·后端·maven
未来龙皇小蓝7 小时前
策略模式:Spring Bean策略与枚举 Lambda策略
java·windows·spring boot·spring·策略模式
张乔247 小时前
spring boot项目中设置默认的方法实现
java·数据库·spring boot