第7章 监听器Listener

Listener概述

   

   

Listener的使用

使用Listener需要实现相应的Listener接口。

public class SessionListenerTest implements HttpSessionListener {

   

public void sessionCreated(HttpSessionEvent se) {

HttpSession session = se.getSession();

System.out.println("新创建了一个session: " + session);

}

   

public void sessionDestroyed(HttpSessionEvent se) {

HttpSession session = se.getSession();

System.out.println("销毁了一个session: " + session);

}

   

}

以上代码实现了HttpSessionListener接口。创建Session时会是服务器调用SessionCreated()方法,销毁Session时服务器调用sessionDestroyed()方法。他们都以HttpSessionEvent对象为参数,可以从该参数中获取session。Listener需要在web.xml中配置才能生效。

配置如下:

<listener>

<listener-class>

com.helloweenvsfei.listener.SessionListenerTest

</listener-class>

</listener>

   

   

Listener的分类

1.监听对象的创建与销毁

HttpSessionListener,HttpContextListener,HttpRequestListener分别用于Session,context,request的创建与销毁。

可以一个类实现多个Listener接口,如下代码:

   

   

2.监听对象的属性变化

   

代码如下:

   

   

   

3.监听Session内的对象

HttpSessionBindingListener和HttpSessionActivationListener

   

HttpSessionBindingListener:当对象被放到Session时执行valueBound(HttpSessionBinding event)方法,对象被移除时执行valueUnbound(HttpSessionBinding event)方法。对象必须实现该Listener接口。

   

HttpSessionActivationListener:服务器关闭时,会将Session内的内容保存到硬盘上,这个过程叫钝化。服务器启动时会将硬盘内容加载进来。当Session里的对象被钝化时会执行sessionWillPassivate(HttpSessionEvent event),当对象被加载时执行sessionDidActivate(HttpSessionEvent event)。对象必须实现该listener接口。

Listener使用案例(单态登陆)

public class LoginSessionListener implements HttpSessionAttributeListener {

   

Log log = LogFactory.getLog(this.getClass());

   

Map<String, HttpSession> map = new HashMap<String, HttpSession>();

   

public void attributeAdded(HttpSessionBindingEvent event) {

   

String name = event.getName();

   

// 登录

if (name.equals("personInfo")) {

   

PersonInfo personInfo = (PersonInfo) event.getValue();

   

if (map.get(personInfo.getAccount()) != null) {

   

// map 中有记录,表明该帐号在其他机器上登录过,将以前的登录失效

HttpSession session = map.get(personInfo.getAccount());

PersonInfo oldPersonInfo = (PersonInfo) session

.getAttribute("personInfo");

   

log.info("帐号" + oldPersonInfo.getAccount() + "在"

+ oldPersonInfo.getIp() + "已经登录,该登录将被迫下线。");

   

session.removeAttribute("personInfo");

session.setAttribute("msg", "您的帐号已经在其他机器上登录,您被迫下线。");

}

   

// 将session以用户名为索引,放入map中

map.put(personInfo.getAccount(), event.getSession());

log.info("帐号" + personInfo.getAccount() + "在" + personInfo.getIp()

+ "登录。");

}

}

   

public void attributeRemoved(HttpSessionBindingEvent event) {

   

String name = event.getName();

   

// 注销

if (name.equals("personInfo")) {

// 将该session从map中移除

PersonInfo personInfo = (PersonInfo) event.getValue();

map.remove(personInfo.getAccount());

log.info("帐号" + personInfo.getAccount() + "注销。");

}

}

   

public void attributeReplaced(HttpSessionBindingEvent event) {

   

String name = event.getName();

   

// 没有注销的情况下,用另一个帐号登录

if (name.equals("personInfo")) {

   

// 移除旧的的登录信息

PersonInfo oldPersonInfo = (PersonInfo) event.getValue();

map.remove(oldPersonInfo.getAccount());

   

// 新的登录信息

PersonInfo personInfo = (PersonInfo) event.getSession()

.getAttribute("personInfo");

   

// 也要检查新登录的帐号是否在别的机器上登录过

if (map.get(personInfo.getAccount()) != null) {

// map 中有记录,表明该帐号在其他机器上登录过,将以前的登录失效

HttpSession session = map.get(personInfo.getAccount());

session.removeAttribute("personInfo");

session.setAttribute("msg", "您的帐号已经在其他机器上登录,您被迫下线。");

}

map.put("personInfo", event.getSession());

}

   

}

   

}

代码详解:

每次用户登录时都会将JavaBean personinfo对象放入到session中,此时会触发监听器LoginSessionListener中的attributeAdded方法,该方法获取personinfo的账号并与已有的map集合中信息比对,看是否有重复的,如果有重复的,则获取重复的session,并去除该session的personinfo信息。

   

HttpSession session = map.get(personInfo.getAccount());

session.removeAttribute("personInfo");

session.setAttribute("msg", "您的帐号已经在其他机器上登录,您被迫下线。");

   

以上代码之所以可以去除原有登陆信息的原因如下:

在Java中参数传递都是传的引用,因此Map集合中的session都是原始session的引用。

   

代码HttpSession session = map.get(personInfo.getAccount());获得的便是原始的session。因此删除该session的personInfo便是删除原始session的personInfo。

   

   

   

posted @ 2016-05-22 22:17  且听风吟-wuchao  阅读(236)  评论(0编辑  收藏  举报