Java下的Session监控:HttpSessionListener HttpSessionAttributeListener || HttpSessionBindingListener

这一块叫做简易的Session管理,因为集成原因被推到后期,方案就白做了,就来发挥点光和热给我可怜的博客添点料吧。

其实之前主要想用想用HttpSessionBindingListener,后来发现它必须添加进Session中才能起作用,所以就放弃了,具体可以参考这篇http://www.cnblogs.com/shencheng/archive/2011/01/07/1930227.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);
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值