Web-监听器

作用

监听域对象(请求request、会话session、应用servletContext)的创建和销毁

监听域对象的属性变更

监听HttpSession中JavaBean的状态改变(了解)

分类

第一类

监听域对象的创建和销毁

域对象类型监听器对应方法描述
ServletContextServletContextListenercontextInitializedapplication初始化
contextDestroyedapplication销毁
HttpSessionHttpSessionListenersessionCreatedsession创建
sessionDestroyedsession销毁
HttpServletRequestServletRequestListenerrequestInitializedrequest创建
requestDestroyedrequest销毁

第二类

监听域对象的属性变更

域对象类型监听器对应方法描述
ServletContextServletContextAttributeListenerattributeAdded添加属性
attributeRemoved删除属性
attributeReplaced修改属性值
HttpSessionHttpSessionAttributeListenerattributeAdded添加属性
attributeRemoved删除属性
attributeReplaced修改属性值
HttpServletRequestServletRequestAttributeListenerattributeAdded添加属性
attributeRemoved删除属性
attributeReplaced修改属性值

第三类

监听HttpSession中JavaBean的状态改变(了解)

第三类监听器非常特殊,这类监听器不用配置

在JavaBean上,JavaBean可以自己感知在session中状态

域对象类型监听器对应方法描述
HttpSessionHttpSessionBindingListenervalueBound绑定
valueUnbound解除绑定
HttpSessionHttpSessionActivationListenersessionWillPassivate序列化(钝化)
sessionDidActivate反序列化(活化)

session的钝化与活化

​ session 钝化本质就是服务器把内存中的session对象序列化到存储设备中,活化就是通过反序列化将session对象从存储设备上进行恢复 session 数据正常是存放在服务器内存当中的,当网站有大量用户访问时,服务器会创建大量的会话,这会占用大量的服务器内存资源,直接影响Web服务器的性能。此时服务器会将不常使用的session对象保存到文件系统或数据库中以节省内存开销,此即为session的钝化。当需要使用时再重新加载到内存,就称为session的活化 除此以外,Tomcat服务器在以下几种情况时也会执行session的钝化和活化操作 当服务器因为某些原因或因维护的需要进行关闭或短暂重启时,为了不丢失当前的会话信息以便在重启之后能够恢复会话,Tomcat服务器会将当前内存中的session对象钝化到服务器文件系统中,待系统恢复后再进行活化 另一种情况是当Web应用被服务器重新加载时,内存中的session对象也会被钝化到服务器的文件系统中,应用加载完毕后再进行活化 需要注意的是,session钝化操作时,session作用域中的变量只有实现了java.io.Serializable接口才能被钝化存储,否则将在钝化时被丢弃 如果需要在session钝化或者活化时执行特定的操作,可以将一个实现了javax.servlet.http.HttpSessionActivationListener接口的类(同时应实现java.io.Serializable接口)实例放入session作用域,通过该接口的sessionWillPassivate()方法和sessionDidActivate( )方法即可在session钝化和活化时执行所需的操作 HttpSessionActivationListener类型的监听器同样不需要在web.xml文件中进行声明、将其实例放入session作用域即可

案例

分析

统计在线人数

统计在线登录人数

需要使用三个监听器

  1. 监听servletContext对象的创建:该对象创建时,初始化两个key,用于保存在线人数和在线登录人数

  2. 监听session对象的创建和销毁:统计在线人数的增和减

  3. 监听session对象的属性变更:统计在线登录人数的增减

// 利用Java多实现的特性同时实现三个监听接口
//ServletContextListener:监听ServletContext对象的创建
//HttpSessionListener:监听HttpSession对象的创建和销毁
//HttpSessionAttributeListener:监听HttpSession对象的属性变更
@WebListener
public class CountListener implements ServletContextListener, HttpSessionListener, HttpSessionAttributeListener {
    /*************************ServletContextListener的方法***********************/
    //ServletContext对象创建时执行的方法:初始化两个保存在线人数、在线登录人数数据
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        //通过形参获取servletContext
        ServletContext servletContext = servletContextEvent.getServletContext();
        servletContext.setAttribute("onlineUserNum", 0);
        servletContext.setAttribute("onlineLoginUserNum", 0);
    }
    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
    }
    /*************************HttpSessionListener的方法***********************/
    // 创建一个执行一次
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        ServletContext sc = httpSessionEvent.getSession().getServletContext();
        // 获取Session值并+1
        Integer onlineUserNum = (Integer) sc.getAttribute("onlineUserNum");
        sc.setAttribute("onlineUserNum", ++onlineUserNum);
    }
    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        HttpSession session = httpSessionEvent.getSession();
        ServletContext sc = session.getServletContext();
        Integer onlineUserNum = (Integer) sc.getAttribute("onlineUserNum");
        sc.setAttribute("onlineUserNum", --onlineUserNum);
        Object loginUser = session.getAttribute("loginUser");
        if (null != loginUser) {
            Integer onlineLoginUserNum = (Integer) sc.getAttribute("onlineLoginUserNum");
            sc.setAttribute("onlineLoginUserNum", --onlineLoginUserNum);
        }
    }
    /*************************HttpSessionAttributeListener的方法***********************/
    @Override
    public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
        //获取向session对象中保存的key的名称
        String name = httpSessionBindingEvent.getName();
        ServletContext sc = httpSessionBindingEvent.getSession().getServletContext();
        //在线登录人数加1
        if ("loginUser".equals(name)) {
            Integer onlineLoginUserNum = (Integer) sc.getAttribute("onlineLoginUserNum");
            sc.setAttribute("onlineLoginUserNum", ++onlineLoginUserNum);
        }
    }
    @Override
    public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
        //获取向session对象中保存的key的名称
        String name = httpSessionBindingEvent.getName();
        ServletContext sc = httpSessionBindingEvent.getSession().getServletContext();
        //在线登录人数加1
        if ("loginUser".equals(name)) {
            Integer onlineLoginUserNum = (Integer) sc.getAttribute("onlineLoginUserNum");
            sc.setAttribute("onlineLoginUserNum", --onlineLoginUserNum);
        }
    }
    @Override
    public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值