与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()方法。

转载于:https://www.cnblogs.com/Mike_Chang/p/10060874.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值