关于Listener监听的session的定时销毁

1、需要通过HttpSessionListener监听session的创建,并获取所有的session对象。用List集合来保存session对象。

public void sessionCreated(HttpSessionEvent se) {
        // 1、通过session监听器获取所有的事件源对象session
        HttpSession session = se.getSession();
        // 2、获取ServletContext对象,
        ServletContext context = session.getServletContext();
        // 3、获取servletContext对象的List<HttpSession>集合
        List<HttpSession> ss = (List<HttpSession>) context.getAttribute("ss");
        // 4、将获取的所有session对象存到集合中
        ss.add(session);
        System.out.println("创建了session对象" + session.getId());

    }

2、而List集合可以保存在ServletContext对象中。 当服务器打开之后就会创建ServletContext对象,将保存session的集合保存到ServletContext对象中。

        // 1、创建集合ss保存session对象
        final List<HttpSession> ss = (Collections
                .synchronizedList(new ArrayList<HttpSession>()));
        // 2、通过事件源获取事件对象  将集合ss保存到                ServletContext对象中 
        ServletContext context = sce.getServletContext();
        context.setAttribute("ss", ss); 
    }

3、怎样判断session对象过期?

从ServletContext中的List集合中得到所有的session.
可以通过session的一个方法getLastAccessedTime获得到session最后使用时间,使用当前时间与其进行计算就可以知道session多长时间没有使用。

        for(int i=0;i<ss.size();i++){
                long time = System.currentTimeMillis()
                            - s.getLastAccessedTime();
                    if (time > 5000) {
                System.out.println("session失效,销毁" +s.getId());
                 ss.remove(s);
                 s.invalidate();
         }
必须使用Timer定时器让判断session过期操作的代码间隔执行。
Timer timer = new Timer();
public void schedule(TimerTask task, long delay,long period)
task = new TimerTask() {
            @Override
            public void run() {
            }
    }
task - 所要安排的任务。
delay - 执行任务前的延迟时间,单位是毫秒。
period - 执行各后续任务之间的时间间隔,单位是毫秒。 
Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                // 3、获取session并判断session是否失效
                // 内部类,ss需要final
                System.out.println("开始扫描。。。。。");
                for (Iterator<HttpSession> it = ss.iterator(); it.hasNext();) {
                    HttpSession s = it.next();
                    // 使用session的getLastAccessedTime()判断最后一次访问该session的时间
                    long time = System.currentTimeMillis()
                            - s.getLastAccessedTime();
                    if (time > 5000) {
                        System.out.println("session失效,销毁" + s.getId());
                        // ss.remove(s);
                        // 在循环遍历集合时不能一边add另外一边又进行remove这样就会报错java.util.ConcurrentModificationException
                        it.remove();
                        s.invalidate();
                    }
                }

            }
        }, 1000, 3000);

问题1.在使用集合保存session时,应该使用不存在线程安全问题的List集合.

>  ArrayList是线程不安全的,多线程问题,应该使用线程安全的list集合 Collections工具类的方法synchronizedList(List<T> list)

问题2:在使用集合操作时,不可以即进行add又进行remove及遍历操作。使用迭代器进行移除。

>remove
void remove()
从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。每次调用 next 只能调用一次此方法。如果进行迭代时用调用此方法之外的其他方式修改了该迭代器所指向的 collection,则迭代器的行为是不确定的。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值