与HttpSession相关的监听器

概述

与HttpSession相关的监听器有四个:分别是HttpSessionListener、HttpSessionAttributeListener、HttpSessionBindingListener与HttpSessionActivationListener。


HttpSessionListener

HttpSessionListener是“生命周期监听器”,在HttpSession对象初始化后或结束前,会分别调用sessionCreated()与sessionDestroyed()方法,并传入的HttpSessionEvent,我们可以使用HttpSessionEvent的getSession()取得HttpSession。

声明

方法一:在实现HttpSessionListener的类上标注@WebListener

@WebListener()
public class SomeSessionListener implements HttpSessionListener {}

java Code

方法二:在web.xml中声明

    <listener>
<listener-class>cc.openhome.SomeSessionListener</listener-class>
</listener>

xml Code

应用

假设有个应用程序在用户登录后会使用HttpSession对象来进行会话管理。如果想要在应用程序中加上显示目前已登录在线人数的功能,就可以实现HttpSessionListener接口。例如:

@WebListener()
public class LoginSessionListener implements HttpSessionListener {
private static int count; public static int getCount() {
return count;
} @Override
public void sessionCreated(HttpSessionEvent se) {
LoginSessionListener.count++;
} @Override
public void sessionDestroyed(HttpSessionEvent se) {
LoginSessionListener.count--;
}
}

java Code

可以把这个例子进一步扩充,不只统计在线人数,还可以实现一个查看在线用户信息的列表。


HttpSessionAttributeListener

HttpSessionAttributeListener是“属性改变监听器”,当在会话对象中加入、移除或替换属性时,相对应的attributeAdded()、attributeRemoved()与attributeReplaced()方法就会被调用,并分别传入HttpSessionBindingEvent。HttpSessionBindingEvent有个getName()方法,可以取得属性设置或移除时指定的名称,而getValue()可以取得属性设置或移除时的对象。

声明

方法一:在实现HttpSessionAttributeListener的类上标注@WebListener

@WebListener()
public class HttpSessionAttrListener implements HttpSessionAttributeListener {
@Override
public void attributeAdded(HttpSessionBindingEvent event) {
//...
} @Override
public void attributeRemoved(HttpSessionBindingEvent event) {
//...
} @Override
public void attributeReplaced(HttpSessionBindingEvent event) {
//...
}
}

java Code

方法二:在web.xml中声明

<web-app...>
...
<listener>
<listener-class>cc.openhome.HttpSessionAttrListener</listener-class>
</listener>
...
<web-app>

xml Code


HttpSessionBindingListener

HttpSessionBindingListener是“对象绑定监听器”,当实现此接口的对象被加入HttpSession或从中移除时,就会收到通知,并调用对应的valueBound()与valueUnbound()方法,且传入HttpSessionBindingEvent对象,我们可以通过该对象的getSession()取得HttpSession对象。

声明

这个监听器的实现类不需要通过注释或在web.xml中声明。

Demo

当用户输入正确的名称与密码时,创建User实例,并加入HttpSession。如果我们希望这时程序自动从数据库中加载用户的其他数据,如地址、照片等,或是在日志中记录用户登录的信息,可以让User类实现HttpSessionBindingListener接口,在valueBound()方法中,实现查询数据库并补齐User对象中的相关数据等功能。

package com.test;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException; @WebServlet("/login")
public class Login extends HttpServlet {
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
doPost(request, response);
}
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
String name = request.getParameter("name");
String passwd = request.getParameter("passwd");
// 假设用户的名称和密码都正确
User user = new User();
user.setName(name);
user.setPasswd(passwd);
// 加入session
HttpSession session = request.getSession();
session.setAttribute("UUID", user);
// 检查属性有没有补全
User user2 = (User) session.getAttribute("UUID");
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
System.out.println(user2);
response.getWriter().write(user2.toString());
}
}

Login Servlet

package com.test;

import javax.servlet.*;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener; @WebListener
public class User implements HttpSessionBindingListener {
private String name;
private transient String passwd;
private String sex;
private Integer age; public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", passwd='" + passwd + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
'}';
}
@Override
public void valueBound(HttpSessionBindingEvent event) {
try {
Thread.sleep(1000); // 测试这个方法是不是阻塞的。结果:是阻塞的,页面一直会等待
} catch (InterruptedException e) {
e.printStackTrace();
}
User user = (User) event.getValue();
user.setAge(18);
user.setSex("女");
}
@Override
public void valueUnbound(HttpSessionBindingEvent event) { }
}

User 实体类

测试地址

http://127.0.0.1/login?name=zs&passwd=123

测试结果

User{name='zs', passwd='123', sex='女', age=18}


HttpSessionActivationListener

HttpSessionActivationListener是“对象迁移监听器”,其中定义了两个方法sessionWillPassivate()、sessionDidActivate()。很多情况下,几乎不会使用到HttpSessionActivationListener。在使用到分布式环境时,应用程序的对象可能分散在多个JVM中。当HttpSession要从一个JVM迁移至另一个JVM时,必须先在原本的JVM上序列化所有的对象,在这之前若对象有实现HttpSessionActivationListener,就会调用sessionWillPassivate()方法,如果HttpSession中有些对象类成员无法作序列化,就可以做些替代处理。而HttpSession迁移至另一个JVM后,会对所有对象作反序列化,此时会调用sessionDidActivate()方法。

上一篇:ODAC(V9.5.15) 学习笔记(十)TVirtualTable


下一篇:USB移动硬盘WinPE启动盘的制作方法