您的位置:首页 > 理论基础 > 计算机网络

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也是可以的

比如:

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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: