目前遇到这样的问题:


用户登录之后,不允许同时登录多个用户(这个已经实现)。但是如果用户以外关闭了浏览器之后,要等到session超时才能 再一次登录,真是太悲剧了。


so。。。现在的解决方案便是,允许第二次登录,登录之后要将第一次登录的session销毁



借助weblogic.jar 反射获取servletContext 中的sessionContext,然后将其opensession属性中的sessionId 删除即可达到目的,代码如下:(我们的项目是将用户第一次登录的session存放到了缓存中去,在用户第二次进来的时候会先获取上一次的session,存在的话就将其从servletContext中删掉)


ServletContext scope = (ServletContext)request.getSession().getServletContext();

Class clazz = weblogic.servlet.internal.WebAppServletContext.class;

Field f = clazz.getDeclaredField("sessionContext");

f.setAccessible(true);


//--取得session context

weblogic.servlet.internal.session.SessionContext sc = (weblogic.servlet.internal.session.SessionContext)f.get(scope);

clazz = weblogic.servlet.internal.session.SessionContext.class;

f = clazz.getDeclaredField("openSessions");

f.setAccessible(true);


//--拿到终的sessionMap

Hashtable sessionMap = (Hashtable)f.get(sc);

//第一种直接删除该sessionID

System.out.println("要删除的sessiongid "+loginSession.getId()+"==========================");

System.out.println("sessionMap 中是否含有将要删除的id"+ sessionMap.containsKey(loginSession.getId().split("!")[0])+"================");

sessionMap.remove(loginSession.getId().split("!")[0]);


效果:

打开一个浏览器登录xxx用户

再打开一个浏览器登录xxx用户

然后再在第一个浏览器中点击任意链接会跳转到登录页面。


---------------------------新增问题


以上逻辑适用于同一台服务器或着同一台服务器上的集群 均可以实现。

但是:

我们的系统由于用了webloic部署了集群(集群在多台服务器上)之后,上面的逻辑便不适用了,所以给出以下解决方案。


因为集群是weblogic 做的,对于session的保持,销毁都可以从weblogic获知。

目前做出的方案是: 登录的时候在membercache保存当前sessionid ,通过拦截器对比membercache中的值跟当前session的值,如果不一样,利用ServletAuthentication.invalidateAll(request) 销毁session即可