Java监听器案例

  • 统计当前在线用户

- 创建监听器类

 1 public class CountNumListener implements HttpSessionListener {
 2     @Override
 3     public void sessionCreated(HttpSessionEvent se) {
 4         //通过事件对象获取ServletContext
 5         ServletContext context = se.getSession().getServletContext();
 6         Integer count = (Integer) context.getAttribute("count");
 7         if (count == null) {
 8             context.setAttribute("count",1);
 9         }
10         count++;
11         context.setAttribute("count",count);
12     }
13 
14     @Override
15     public void sessionDestroyed(HttpSessionEvent se) {
16         ServletContext context = se.getSession().getServletContext();
17         Integer count = (Integer) context.getAttribute("count");
18         count--;
19         context.setAttribute("count",count);
20     }
21 }

- 注册监听器

1 <listener>
2     <listener-class>com.xym.listener.CountNumListener</listener-class>
3 </listener>

- 测试代码

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

此方式只能统计一个近似值,因为当客户离开网站时,服务器端的Session没有及时销毁,或是客户端同时开两个浏览器窗口访问时都会造成数据的不准确。

  • 自定义Session扫描器
 1 public class SessionScanner implements HttpSessionListener, ServletContextListener {
 2 
 3     // 经常增删应使用链表容器,容器会被并发访问,应使用同步容器
 4     private static List<HttpSession> list = Collections.synchronizedList(new LinkedList<>());
 5     private static final Object lock = new Object();
 6 
 7     @Override
 8     public void sessionCreated(HttpSessionEvent se) {
 9         HttpSession session = se.getSession();
10         System.out.println("Session被创建,ID:" + se.getSession().getId());
11         // 与定时器执行销毁时共享锁 否则会有并发修改异常
12         synchronized (lock) {
13             list.add(session);
14         }
15     }
16 
17     @Override
18     public void sessionDestroyed(HttpSessionEvent se) {
19         System.out.println("Session被销毁,ID:" + se.getSession().getId());
20     }
21 
22     @Override
23     public void contextInitialized(ServletContextEvent sce) {
24         // 服务器启动时创建一个定时器 每30秒执行任务
25         Timer timer = new Timer();
26         timer.schedule(new MyTask(),0,30*1000);
27     }
28 
29     @Override
30     public void contextDestroyed(ServletContextEvent sce) {
31 
32     }
33 
34     static class MyTask extends TimerTask{
35 
36         @Override
37         public void run() {
38             System.out.println("定时器执行!");
39             synchronized (lock) {
40                 // 应获取可迭代修改的迭代器,用迭代器的方法移除容器内的Session
41                 ListIterator<HttpSession> iterator = list.listIterator();
42                 while (iterator.hasNext()) {
43                     HttpSession session = iterator.next();
44                     // 如果Session无活跃时长大于30秒 则摧毁
45                     if (System.currentTimeMillis() - session.getLastAccessedTime() > 30 * 1000) {
46                         session.invalidate();
47                         iterator.remove();
48                     }
49                 }
50             }
51         }
52     }
53 }

同时实现两个监听器,在服务器启动时会创建定时器,在创建Session时会加入自定义的容器内自行管理,不再由服务器管理。

此Session扫描器启动的时间跟Session创建的时间会有30秒的时间差

转载于:https://www.cnblogs.com/aikf/p/10118716.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值