自定义session扫描器
为何要自定义session扫描器
由于服务器来管理session的销毁不怎么靠谱,因此很多网站都会自己定义一个session扫描器来管理session的创建和销毁。
实现思路
首先,创建一个session扫描器类SessionScanner,然后继承HttpSessionListener,在sessionCreated方法中,获取session,这个时候我们需要创建一个容器,用来存放session,然后继承ServletContextListener,在contextInitialized方法(在web应用启动时执行此方法)中定义一个定时器,将一段时间内没有用到的session销毁。
代码实现如下:
package com.ccfdod.web.listener; import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Timer;
import java.util.TimerTask; import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener; public class SessionScanner implements HttpSessionListener,ServletContextListener { //这里使用Collections.synchronizedList(List<T> list)是考虑到线程并发问题,因此将容器设置为线程安全的
//Collections为集合的帮助类,如发现具体的集合类不能提供某些功能,可查看该帮助类的方法,看是否存在该功能
//另外使用LinkedList而不使用ArrayList的原因是ArrayList底层为数据,用来做增删改查不适合,效率较低
private List<HttpSession> list = Collections.synchronizedList(new LinkedList<HttpSession>()); //定义一个锁对象,用于解决线程并发时,session的添加和除去若同时进行,会引起定时器中对list的session操作时,产生迭代器并发修改异常
private Object lock = new Object();
public void contextInitialized(ServletContextEvent sce) {
//这里使用Timer作为定时器,当然也可以使用其他的
Timer timer = new Timer();
timer.schedule(new MyTask(list,lock), 0, 30*1000);
} public void sessionCreated(HttpSessionEvent se) {
//第一次调用getSession时,服务器创建一个session
//但在jsp中,默认调用request.getSession()方法,创建一个session
//但可以在jsp文件的第一行,添加session="false",这样在访问jsp页面时,就不会创建session了
HttpSession session = se.getSession();
System.out.println(session + "被创建了!!");
synchronized (lock) { //锁旗标
list.add(session);
}
}
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println(se.getSession() + "被销毁了");
} public void contextDestroyed(ServletContextEvent sce) { }
} class MyTask extends TimerTask{
private List list;
private Object lock;
public MyTask(List list,Object lock){
this.list = list;
this.lock = lock;
}
@Override
public void run() {
System.out.println("定时器执行!!");
synchronized (this.lock) {
//ListIterator为Iterator的子类,提供了对crud操作
ListIterator it = list.listIterator();
while(it.hasNext()){
HttpSession session = (HttpSession) it.next();
if((System.currentTimeMillis()-session.getLastAccessedTime())>30*1000){
session.invalidate();
//list.remove(session); //迭代器并发修改异常
//若对集合迭代,需要对集合进行crud操作时,使用迭代器的方法对集合进行crud
it.remove();
}
}
}
}
}
最后
将SessionScanner添加至web.xml中
自定义session扫描器的更多相关文章
- 监听器应用【统计网站人数、自定义session扫描器、踢人小案例】
从第一篇已经讲解过了监听器的基本概念,以及Servlet各种的监听器.这篇博文主要讲解的是监听器的应用. 统计网站在线人数 分析 我们在网站中一般使用Session来标识某用户是否登陆了,如果登陆了, ...
- python_way ,自定义session
python_way ,自定义session container = {} #可以是数据库,可以是缓存也可以是文件 class Session: def __init__(self, handler) ...
- 可灵活扩展的自定义Session状态存储驱动
Session是互联网应用中非常重要的玩意儿,对于超过单台部署的站点集群,都会存在会话共享的需求.在web.config中,微软提供了sessionstate节点来定义不同的Session状态存储方式 ...
- Asp.net Mvc 自定义Session (二)
在 Asp.net Mvc 自定义Session (一)中我们把数据缓存工具类写好了,今天在我们在这篇把 剩下的自定义Session写完 首先还请大家跟着我的思路一步步的来实现,既然我们要自定义Ses ...
- Asp.net Mvc 自定义Session (一),
大家都知道用系统默认的session 会存在这样的问题 如果用户过多的话 session 会自动消亡,而且不能支持分布式和集群. 这系列博客主要讲解 怎样 解决用户过多的session自动消亡,和分 ...
- Spring自定义类扫描器 ClassPathScanningCandidateComponentProvider
项目中有个需求 读取xml文件,然后 对xml文件进行解析,比如如果是 Gender=0/1的话,分别代表男女. 所以需要在构造函数之后,初始化bean之前进行过滤解析 xml文件: <inte ...
- Tronado自定义Session
这里就不一一诉说Session和Cookie直接的关系了,下面以一张图来概括: 下面是一个简单的Tornaod自定义Session的例子,看完后你可能会明白为什么我们在Django里可以直接使用req ...
- 简单的自定义Session
有关Session.Cookie机制建议参考文章:CookieSession机制详解,写的很详细,不再赘述 本篇文章通过一个简单的案例揭秘Session机制以及和Cookie的区别和联系: 服务器端代 ...
- Tornado 自定义session,与一致性哈希 ,基于redis 构建分布式 session框架
Tornado 自定义session,与一致性哈希 ,基于redis 构建分布式 session import tornado.ioloop import tornado.web from myhas ...
随机推荐
- Android多媒体-MediaRecorder 录制音视频
不多说,直接上代码,有具体凝视 MyAudioRecord.java import java.io.File; import java.io.IOException; import android.a ...
- Visual Studio 2015 & C#6.0
Visual Studio 2015 & C#6.0 试用报告,持续更新. 昨天早上看到了.net开源的消息,我是非常兴奋的,毕竟局限于Windows的.NET经常被人唾弃.VB暂且不 ...
- Mac OSX系统安装和配置Zend Server 6教程(2)
继上一节安装好Zend Server 6以后,我们需要修改配置文件.首先修改服务器监听端口.默认的情况下Zend Server 6安装以后的端口是10088.一般开发者使用的都是HTTP默认端口80. ...
- js 监控浏览器关闭事件
代码如下: <!DOCTYPE html> <html> <head> <title>监控浏览器关闭事件</title> </head ...
- SSIS如何引用外部DLL
原文:SSIS如何引用外部DLL 当SSIS引用外部的DLL时,外部的DLL须满足以下条件: 1. DLL是强命名. 2. 加入到GAC (C:\WINDOWS\assembly),直接把DLL拉进目 ...
- .Net中批量添加数据的几种实现方法比较
在.Net中经常会遇到批量添加数据,如将Excel中的数据导入数据库,直接在DataGridView控件中添加数据再保存到数据库等等. 方法一:一条一条循环添加 通常我们的第一反应是采用for或for ...
- C语言中的内存对齐
最近看了好多,也编了好多C语言的浩强哥书后的题,总觉的很不爽,真的真的好怀念linux驱动的代码,好怀念那下划线,那结构体,虽然自己还很菜. 同时看了一遍陈正冲老师的C语言深度剖析,收益很多,又把唐老 ...
- storm安装(2)ZeroMQ、JZMQ、Python、Java环境的安装
2.ZeroMQ安装 把安装本件zeromq-2.1.7.tar.gz拷贝到home文件路径下, 给文件加入权限 chmod +x /home/zeromq-2.1.7.tar.gz 解压文件 tar ...
- silverlight中datagrid数据到处excel
首先新建一个DataGrdiExtensions类,代码为: public static class DataGridExtensions { /// <summary> /// 导出dg ...
- [Usaco2008 Mar]River Crossing渡河问题[简单DP]
Description Farmer John以及他的N(1 <= N <= 2,500)头奶牛打算过一条河,但他们所有的渡河工具,仅仅是一个木筏. 由于奶牛不会划船,在整个渡河过程中,F ...