Java下的Session监控:HttpSessionListener HttpSessionAttributeListener || HttpSessionBindingListener
2015-08-04 16:29
281 查看
这一块叫做简易的Session管理,因为集成原因被推到后期,方案就白做了,就来发挥点光和热给我可怜的博客添点料吧。
其实之前主要想用想用HttpSessionBindingListener,后来发现它必须添加进Session中才能起作用,所以就放弃了,具体可以参考这篇/article/5480572.html
官方手册https://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/http/HttpSession.html
现在有这样一个需求:
1. Admin可以改任意用户的密码。
2. 被更改的用户需要重新登录。
那么使用监听器来监听所有的session无疑是最容易想到的方案之一。因而选用了无敌的HttpSessionListener,可以在session被创建和销毁的时候获取值,从而方便我们操作。
Step 1: Web.xml
这里是配置监听的实现类。
<listener>
<listener-class>*.SessionManagement</listener-class>
</listener>
Step 2: SessionMangement.java
这里我就破坏了设计模式,其实用Interface来继承HttpSessionListener也是可以的
比如:
当然也可以在实现类中实现:
那么实现思路是怎样?做个List来记录创建和销毁的session,而在session需要改变的地方去更新记录了的session状态。
这样子我们就记录了Session的改变,并且做了对应的操作。
而在实际案例中,这样远远不够,因为客户端会产生大量无效的session和与我们相悖的session。那么如何甄别有效的session就是addLoginSessions需要考虑的问题。
在本案例中,session被先创建,而后登陆信息被记录在attribute中,按照上面的方法,其实我们会错过正确的session。该怎么办?
还好,HttpSessionAttributeListener为Attribute的改变提供了解决方案。
同时监听器,实现方法与HttpSessionListener类似,我们需要重写三个方法:
在这三个对应的需要的方法里,实现我们的操作就可以了。
是不是很简单,其实就是两步:配置对应的web.xml和实现对应的接口即可。
下面就是我实现的一个方案,当然略去了很多细节,给大家做个参考吧。
好了上代码。
其实之前主要想用想用HttpSessionBindingListener,后来发现它必须添加进Session中才能起作用,所以就放弃了,具体可以参考这篇/article/5480572.html
官方手册https://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/http/HttpSession.html
现在有这样一个需求:
1. Admin可以改任意用户的密码。
2. 被更改的用户需要重新登录。
那么使用监听器来监听所有的session无疑是最容易想到的方案之一。因而选用了无敌的HttpSessionListener,可以在session被创建和销毁的时候获取值,从而方便我们操作。
Step 1: Web.xml
这里是配置监听的实现类。
<listener>
<listener-class>*.SessionManagement</listener-class>
</listener>
Step 2: SessionMangement.java
这里我就破坏了设计模式,其实用Interface来继承HttpSessionListener也是可以的
比如:
public interface SessionManagementInterface extends HttpSessionListener
当然也可以在实现类中实现:
public class SessionManagement implements HttpSessionListener
那么实现思路是怎样?做个List来记录创建和销毁的session,而在session需要改变的地方去更新记录了的session状态。
@Override public void sessionCreated (HttpSessionEvent event){ HttpSession session = event.getSession(); addLoginSessions(session); } @Override public void sessionDestroyed(HttpSessionEvent event){ HttpSession session = event.getSession(); removeLoginSessions(session); }
这样子我们就记录了Session的改变,并且做了对应的操作。
而在实际案例中,这样远远不够,因为客户端会产生大量无效的session和与我们相悖的session。那么如何甄别有效的session就是addLoginSessions需要考虑的问题。
在本案例中,session被先创建,而后登陆信息被记录在attribute中,按照上面的方法,其实我们会错过正确的session。该怎么办?
还好,HttpSessionAttributeListener为Attribute的改变提供了解决方案。
同时监听器,实现方法与HttpSessionListener类似,我们需要重写三个方法:
@Override public void attributeAdded(HttpSessionBindingEvent event){ } @Override public void attributeRemoved(HttpSessionBindingEvent event){ } @Override public void attributeReplaced(HttpSessionBindingEvent event) { }
在这三个对应的需要的方法里,实现我们的操作就可以了。
是不是很简单,其实就是两步:配置对应的web.xml和实现对应的接口即可。
下面就是我实现的一个方案,当然略去了很多细节,给大家做个参考吧。
好了上代码。
public class SessionManagementImpl implements SessionManagement , HttpSessionAttributeListener{ private static final Map<String, Map<String, HttpSession>> loginSessions = new HashMap<String, Map<String, HttpSession>>(); private static final Map<String, String> reverseKeyLoginSessions = new HashMap<String, String>(); @Override public void attributeAdded(HttpSessionBindingEvent event){ HttpSession httpSession = event.getSession(); Object attr = httpSession.getAttribute("UserInfo"); if (attr != null && (attr instanceof Info)) { Info Info = (Info) attr; if (Info.getUser() != null) { updatedLoginSessions(Info, httpSession); } } } @Override public void attributeRemoved(HttpSessionBindingEvent event){ HttpSession httpSession = event.getSession(); if (reverseKeyLoginSessions.containsKey(httpSession.getId())) { Object attr = httpSession.getAttribute("UserInfo"); if (attr != null && (attr instanceof Info)) { Info Info = (Info) attr; if (Info.getUser() != null) { updatedLoginSessions(Info, httpSession); }else { removeLoginSessions(httpSession); } } else { removeLoginSessions(httpSession); } } } @Override public void attributeReplaced(HttpSessionBindingEvent event) { } @Override public boolean isLoginSessionIdExist(String currentKey, HttpSession httpSession){ if (loginSessions.containsKey(currentKey)){ if (loginSessions.get(currentKey).containsKey(httpSession.getId())){ return true; }else { return false; } } else{ return false; } } @Override public void addLoginSessions(final HttpSession session){ Object attr = session.getAttribute("UserInfo"); if (attr != null && (attr instanceof Info)) { Info Info = (Info) attr; if (Info.getUser() != null) { if (isLoginSessionIdExist(Info.getSessionId(), session)) { updatedLoginSessions(Info, session); } else { if (loginSessions.containsKey(Info.getSessionId())) { loginSessions.get(Info.getSessionId()).put(session.getId(), session); reverseKeyLoginSessions.put(session.getId(), Info.getSessionId()); } else { loginSessions.put(Info.getSessionId(), new HashMap<String, HttpSession>() {{ put(session.getId(), session); }}); reverseKeyLoginSessions.put(session.getId(), Info.getSessionId()); } } } } } @Override public void updatedLoginSessions(Info Info, HttpSession session){ if (isLoginSessionIdExist(Info.getSessionId(), session)){ loginSessions.get(Info.getSessionId()).remove(session.getId()); loginSessions.get(Info.getSessionId()).put(session.getId(),session); reverseKeyLoginSessions.remove(session.getId()); reverseKeyLoginSessions.put(session.getId(), Info.getSessionId()); } else { addLoginSessions(session); } } @Override public void invalidLoginSessions(User User){ if (User != null) { if (loginSessions.containsKey(User.getName())) { for (HttpSession httpSession : loginSessions.get(User.getName()).values()){ httpSession.invalidate(); } } } } @Override public void removeLoginSessions(HttpSession session){ if (reverseKeyLoginSessions.containsKey(session.getId())){ loginSessions.get(reverseKeyLoginSessions.get(session.getId()).toString()).remove(session.getId()); if (loginSessions.get(reverseKeyLoginSessions.get(session.getId()).toString()).isEmpty()){ loginSessions.remove(reverseKeyLoginSessions.get(session.getId())); } reverseKeyLoginSessions.remove(session.getId()); } } @Override public void sessionCreated(HttpSessionEvent event){ HttpSession session = event.getSession(); addLoginSessions(session); } @Override public void sessionDestroyed(HttpSessionEvent event){ HttpSession session = event.getSession(); removeLoginSessions(session); } }
相关文章推荐
- 博客搬家。新博客地址 http://fangjian0423.github.io/
- TCP UDP 校验算法
- Http基础(记忆笔记)
- iOS基本网络请求
- php处理http post/get请求
- java web给手机端写接口HttpServletRequest ,HttpServletResponse
- 网络编程中的标准处理函数
- CDN(内容分发网络)
- TCP层的分段和IP层的分片之间的关系 & MTU和MSS之间的关系 (转载)
- TCP/IP协议,HTTP协议
- IP头,TCP头,UDP头,MAC帧头定义(转)
- universalimageloader-disk cache,缓存网络请求
- tcp retransmission问题
- HttpServletResponse对象
- TCP协议详解(四)
- [网络流24题] 05 圆桌聚餐(最大流判满流)
- unp.h及网络编程UNP所有代码的下载
- HTTP协议小结
- HTTP协议小结
- 在Visual Studio 2010里面使用.NET 4.5里面新增加的HttpClient