@pastqing
2015-01-08T17:08:43.000000Z
字数 4360
阅读 2989
java
此文指针对小白, 加上日常记录之用。 小牛, 大牛勿进。
Listener是Servlet的一个高级特性, 它能监听java web程序中的事件, 例如创建、 修改、 删除Session, request, context等。
这里用到两种Listener,分别是HttpSessionBindingListener与HttpSessionActivationListener, 它们的触发时机分别为:
关于钝化:服务器关闭时, 会将Session里的内容保存到硬盘上(保存到哪?I don‘t know),这个就叫钝化。服务器重新启动时, 会将session内容从硬盘中重新加载。
public class PersonInfo implements HttpSessionBindingListener, HttpSessionActivationListener, Serializable {
private String name;
private Date dateCreated;
/**
* 该对象被存入session前调用
* @see HttpSessionBindingListener#valueBound(HttpSessionBindingEvent)
*/
public void valueBound(HttpSessionBindingEvent arg0) {
HttpSession session = arg0.getSession(); //记录它所在的session
String name = arg0.getName(); //得到其在session中的属性名称
System.out.println(this + "被绑定到session " + session.getId() + " name: " + name);
this.setDateCreated(new Date());
}
/**
* 从硬盘中读入session后调用
* @see HttpSessionActivationListener#sessionDidActivate(HttpSessionEvent)
*/
public void sessionDidActivate(HttpSessionEvent arg0) {
HttpSession session = arg0.getSession();
System.out.println(this + "已经成功从硬盘中加载 sessionID:" + session.getId() );
}
/**
* 即将被钝化到硬盘时调用(服务器关闭时, session信息会被保存到硬盘上)
* @see HttpSessionActivationListener#sessionWillPassivate(HttpSessionEvent)
*/
public void sessionWillPassivate(HttpSessionEvent arg0) {
HttpSession session = arg0.getSession();
System.out.println(this + "已经成功钝化到硬盘 sessionID:" + session.getId() );
}
/**
* 从session中移除对象时调用
* @see HttpSessionBindingListener#valueUnbound(HttpSessionBindingEvent)
*/
public void valueUnbound(HttpSessionBindingEvent arg0) {
HttpSession session = arg0.getSession();
String name = arg0.getName();
System.out.println(this + "从session中移除的session, sessionID: " + session.getId() + " name: " + name);
}
这里提一下java序列化Serializable, 这里要用到序列化的原因大概是要往硬盘里写, 那么怎么把对象写进硬盘里呢, 就是将对象序列化后放入内存, 从内存中写到硬盘里。至于Serializable我也不是很懂, 有兴趣可以参考这个文章java序列化
public class LoginListener implements HttpSessionAttributeListener {
//定义一个map用来存放session对象
Map<String, HttpSession> map = new HashMap<String, HttpSession>();
public void attributeAdded(HttpSessionBindingEvent arg0) {
System.out.println("start add");
String name = arg0.getName();
if("personInfo".equals(name)) {
LoginPerson loginPerson = (LoginPerson)arg0.getValue();
if( map.get(loginPerson.getAccount()) != null ) { //若map中存在账号
//账号在不同的会话中登陆, 注销一个, 实现单态登陆
HttpSession session = map.get(loginPerson.getAccount());
LoginPerson oldPerson = (LoginPerson)session.getAttribute("personInfo");
System.out.println("账号 " + oldPerson.getAccount() + " 在 " + oldPerson.getIp() + " 已经登陆, 将被迫下线");
session.removeAttribute("personInfo");
session.setAttribute("msg", "您的账号已在其他机器上登陆");
map.put(loginPerson.getAccount(), arg0.getSession());
System.out.println("账号 " + loginPerson.getAccount() + " 在 " + loginPerson.getIp() + " 登陆");
}
}
}
public void attributeRemoved(HttpSessionBindingEvent arg0) {
System.out.println("start remove");
//注销时调用
String name = arg0.getName();
if( "personInfo".equals(name) ) {
LoginPerson loginPerson = (LoginPerson)arg0.getValue();
map.remove(loginPerson.getAccount());
System.out.println("账号: " + loginPerson.getAccount() + "已注销");
}
}
public void attributeReplaced(HttpSessionBindingEvent arg0) {
System.out.println("start replace");
String name = arg0.getName();
if("personInfo".equals(name)) { //没有注销的情况下, 使用其他账号登陆
LoginPerson oldPerson = (LoginPerson)arg0.getValue();
map.remove(oldPerson); //移除旧的登陆信息
LoginPerson loginPerson = (LoginPerson)arg0.getSession().getAttribute("personInfo"); //新的登陆信息
//验证新的登陆是否在其他会话中登陆
if(map.get(loginPerson.getAccount()) != null ) {
HttpSession session = map.get(loginPerson.getAccount());
session.removeAttribute("personInfo");
session.setAttribute("msg", "您的账号已在其他机器上登陆");
System.out.println("msg已经存入session");
}
map.put(loginPerson.getAccount(), arg0.getSession());
}
}
}