您的位置:首页 > 其它

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

2016-09-25 15:08 330 查看
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,则迭代器的行为是不确定的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: