当前位置: 首页 > news >正文

HttpSessionBindingListener

HttpSessionBindingListener 是一个“自我感知”的监听器,当实现它的对象被放入Session或从Session中移除时,容器会自动调用该对象的相关方法。这对于管理对象在Session生命周期内的行为非常有用。

下面是一个对比表格,帮助你快速理解它与其他监听器的核心区别:

特性HttpSessionBindingListenerHttpSessionAttributeListener
监听目标实现了该接口的对象自身的绑定/解绑事件Session域中所有属性的添加、移除、替换事件
实现位置被存储的JavaBean对象本身独立的监听器类
配置注册无需web.xml或使用@WebListener注册必须通过web.xml@WebListener注册
适用场景对象需要自主管理自己的Session生命周期全局监控Session域内所有属性的变化

🔌 核心机制与接口方法

当一个实现了 HttpSessionBindingListener 接口的对象被绑定到Session(即通过 session.setAttribute("key", object) 方法)时,容器会自动调用该对象的 valueBound 方法。反之,当该对象从Session中被移除(即通过 session.removeAttribute("key")、Session失效或超时)时,容器会自动调用其 valueUnbound 方法。

接口定义了两个核心方法:

  • void valueBound(HttpSessionBindingEvent event): 对象被绑定到Session时触发。
  • void valueUnbound(HttpSessionBindingEvent event): 对象从Session中解除绑定时触发。

📟 实现在线用户跟踪

利用 HttpSessionBindingListener 实现在线用户统计是一个典型应用。它的优势在于,无论用户是正常退出还是Session超时,都能自动触发计数减少,比传统的在登录/注销Servlet中手动管理计数更可靠。

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import java.util.concurrent.atomic.AtomicInteger;public class OnlineUser implements HttpSessionBindingListener {private String username;public OnlineUser(String username) {this.username = username;}@Overridepublic void valueBound(HttpSessionBindingEvent event) {// 当此User对象被添加到Session时,在线人数+1ServletContext application = event.getSession().getServletContext();AtomicInteger onlineCount = (AtomicInteger) application.getAttribute("onlineCount");if (onlineCount == null) {onlineCount = new AtomicInteger(0);application.setAttribute("onlineCount", onlineCount);}int count = onlineCount.incrementAndGet(); // 原子操作,线程安全System.out.println("用户 " + username + " 登录,当前在线人数: " + count);// 这里可以将信息记录到日志文件}@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {// 当此User对象从Session中移除时,在线人数-1ServletContext application = event.getSession().getServletContext();AtomicInteger onlineCount = (AtomicInteger) application.getAttribute("onlineCount");if (onlineCount != null) {int count = onlineCount.decrementAndGet();System.out.println("用户 " + username + " 下线,当前在线人数: " + count);// 判断解绑原因String reason = "未知";try {// 如果Session已失效,调用其方法可能会抛出异常if (event.getSession().isNew()) { // 这是一种粗略的判断方式,实际中可能需要更复杂的逻辑reason = "会话超时或失效";}} catch (IllegalStateException e) {reason = "会话已失效";}System.out.println("下线原因: " + reason);}}// ... getter 和 setter 方法
}

在用户登录成功的Servlet中,你将这个对象放入Session即可自动开始监听:

// 在登录验证成功的逻辑中
HttpSession session = request.getSession();
OnlineUser onlineUser = new OnlineUser(loggedInUsername);
session.setAttribute("onlineUser", onlineUser); // 此行代码将自动触发valueBound方法

在JSP页面中,你可以这样显示在线人数:

当前在线人数:${applicationScope.onlineCount}

🎯 其他应用场景

  1. 资源生命周期管理:如果某个对象在Session期间持有需要手动释放的资源(如临时文件、网络连接),可以在 valueBound 中创建资源,在 valueUnbound 中确保释放。

    @Override
    public void valueUnbound(HttpSessionBindingEvent event) {if (tempFile != null) {tempFile.delete(); // 自动清理临时文件}if (databaseConnection != null) {databaseConnection.close(); // 自动关闭连接}
    }
    
  2. 用户登录记录与统计:除了计数,还可以记录用户登录/登出的具体时间、IP等信息,用于行为分析。

⚠️ 重要注意事项

  1. 触发条件

    • 替换属性:如果使用相同的key将一个新对象绑定到Session,原对象的valueUnbound方法会先被触发,然后新对象的valueBound方法再被触发
    • Session失效:Session超时或调用 session.invalidate() 也会触发所有绑定对象的 valueUnbound 方法。
  2. 无需注册:这是该监听器的一个关键特性。你只需要让JavaBean实现接口,当它的实例被放入Session时,监听功能自动生效,无需在web.xml中进行任何配置

  3. 避免递归调用严禁valueBoundvalueUnbound 方法内对当前对象再次执行绑定或解绑操作,否则会导致栈溢出。

    // 错误示例!这将导致无限递归!
    public void valueBound(HttpSessionBindingEvent event) {event.getSession().setAttribute("myObject", this); // 错误!
    }
    
  4. 序列化问题:在分布式集群环境中,Session对象可能会被序列化(钝化)到硬盘或在不同节点间传输。你的JavaBean需要实现 java.io.Serializable 接口。需要注意的是,钝化和活化过程本身不会触发valueBoundvalueUnbound方法

http://www.dtcms.com/a/405772.html

相关文章:

  • AndroidEventBus 发布者发布一次订阅者接收到多次问题
  • Unity开发CI/CD工具Jenkins的安装(Windows10)
  • 按键精灵安卓/ios辅助工具,脚本开发新手教程ui界面介绍
  • Machine Learning HW4 report: 语者识别 (Hongyi Lee)
  • Android 系统源码级进程保活全方案:从进程创建到后台防护
  • 在hadoop中Job提交的流程
  • 基于Qt和FFmpeg的安卓监控模拟器/手机摄像头模拟成onvif和28181设备
  • 01MemoryOS环境搭建 python3.10
  • 建设部网站职责划定html精美登录界面源码
  • 网站建设基本步骤顺序网站的整体风格
  • Leetcode 146. LRU 缓存 哈希表 + 双向链表
  • VideollaMA 3论文阅读
  • Android 14 系统 ANR (Application Not Responding) 深度分析与解决指南
  • 《红色脉络:一部PLMN在中国的演进史诗 (1G-6G)》 第11篇 | 核心网演进终局:从EPC到5GC——微服务与“云原生”
  • k8s中的NetworkPolicy
  • 【大语言模型】大模型后训练入门指南
  • 【初学】使用 node 编写 MCP Server
  • 阿里云云原生挑战官方用例SPL
  • 销售管理软件免费版什么叫seo优化
  • Apache POI 在 Linux 无图形界面环境下因字体配置问题导致Excel导出失败的解决方案
  • 咨询顾问进阶——146页PPT详解麦肯锡-企业管理整合咨询-组织设计方案【附全文阅读】
  • 力扣995. K 连续位的最小翻转次数
  • Resources$NotFoundException
  • pg下使用 TimescaleDB并创建1亿数据
  • 自动化脚本的操作逻辑与实现
  • UVa12418 Game of 999
  • 基于51单片机的音乐弹奏系统
  • 负载均衡式的在线OJ项目编写(二)
  • 美篇在哪个网站做的外链代发工具
  • Linux高级技巧之集群部署(七)