JavaWeb学习笔记 | 监听器(Listener)

2019-07-31  本文已影响0人  一颗白菜_

1.监听器的简介

1.监听器:

专门用于对其他对象身上发生的事件或状态改变进行监听或相应处理的对象,
当被监视的对象发生情况时立即采取相应的行动。

2.Servlet监听器:

Servlet规范中定义的一种特殊类。
它用于监听web应用程序中的ServletContext,
HttpSession和ServletRequest等域对象的创建与销毁事件,
以及监听这些域对象中的属性发生修改的时间。


2.监听器的分类

按监听的事件类型可以将Servlet监听器分为如下三种类型:
1.监听域对象自身的创建和销毁的事件监听器。
2.监听域对象中的属性的增加和删除的事件监听器。
3.监听绑定到HttpSession域中的某个对象的状态的事件监听器。


3.监听域对象的创建和销毁

1.概括

1.域对象创建和销毁的事件监听器就是用来监听ServletContext,HttpSession,HttpServletRequest这三个对象的创建和销毁的监听器。
2.域对象的创建和销毁时机
创建时机 销毁时机
ServletContext WEB服务器启动时为每个WEB应用程序创建相应的ServletContent对象 WEB服务器关闭时为每个WEB应用程序销毁相应的ServletContent对象
HttpSession 浏览器开始与服务器会话时创建 调用HttpSession.invalidate()或超过了session的最大有效时间间隔或服务器进程被停止
ServletRequest 每次请求开始时被创建 每个访问结束后销毁

2.ServletContentListener

1.监听ServletContext对象被创建或销毁的Servlet监听器
2.使用方法

(1).创建一个实现了ServletContextListener的类,并且实现其中的两个方法。
(2).在web.xml中进行配置即可

3.ServletContextListener是最常用的Listener,可以在当前WEB应用被加载时对当前WEB应用的相关资源进行初始化操作。

例如:创建数据库连接池,创建Spring的IOC容器,读取当前WEB应用的初始化参数等等...

4.示例:

(1).创建实现类:

    public class HelloServletContextListener implements ServletContextListener{
        public HelloServletContextListener() { }
        public void contextInitialized(ServletContextEvent sce) {
          System.out.println("Initialized ..." + sce.getServletContext());
        }
        public void contextDestroyed(ServletContextEvent sce) {
          System.out.println("Destroyed ...");
        }
    }

(2).web.xml中配置:

    <listener>
        <listener-class>HelloServletContextListener</listener-class>
    </listener>
5.相关的API

public void contextInitialized(ServletContextEvent sce){}

ServletContent对象被创建的时候(即当前WEB应用被加载时)
Servlet容器调用该方法

public void contextDestroyed(ServletContextEvent sce){}
ServletContent对象被销毁的时候(即当前WEB应用被卸载时)
Servlet容器调用该方法

API中的参数:ServletContextEvent
ServletContextEvent中只有一个方法如下:
getServletContext():获取ServletContext。

3.ServletRequestListener和HttpSessionListener

1.和ServletContextListener类似。
2.三个域对象的整合示例:

public class HelloServletContextListener implements ServletContextListener,HttpSessionListener, ServletRequestListener {

    public HelloServletContextListener() { }
    public void contextInitialized(ServletContextEvent sce) {
      System.out.println("contextInitialized ...");
    }
    public void contextDestroyed(ServletContextEvent sce) {
      System.out.println("contextDestroyed ...");
    }
    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
        System.out.println("requestDestroyed ...");
    }
    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
        System.out.println("requestInitialized ...");
    }
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        System.out.println("sessionCreated ...");
    }
    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        System.out.println("sessionDestroyed ...");
    }
}
3.利用Listener理解域对象的生命周期

(1).request:是一个请求,当一个响应返回时,即被销毁,当发送一个请求时被创建。
注意:请求转发是一个请求
请求的重定向是两个请求
(2).session:当第一次访问WEB应用的一个JSP或Servlet时,且该JSP或Servlet中还需要创建session对象时,服务器会创建一个session对象。
session销毁(三种情况):session过期,直接调用session的invalidate方法,当前WEB应用被卸载(session可被持久化)。

注意:关闭浏览器并不意味着session被销毁,还可以通过sessionid找到服务器中的session对象。
(3).application:贯穿于当前的WEB应用的生命周期,当前WEB应用被加载时创建,当前WEB应用被卸载时销毁。


4.域对象中属性的变更事件监听器

1.概述

1.域对象中属性的变更的事件监听器就是用来监听ServletContext,HttpSession,HttpServletRequest这三个对象中的属性变更信息事件的监听器。
2.这三个监听器接口分别是ServletContextAttributeListener,HttpSessionAttributeListener和ServletRequestAttributeListener,这三个接口中都定义了三个方法来处理被监听对象中的属性的增加,删除和替换的事件,同一个事件在三个接口中对应的方法名完全相同,只是接受的参数类型不同。

2.ServletContextAttributeListener,HttpSessionAttributeListener和ServletRequestAttributeListener

1.监听ServletContext,HttpSession,ServletRequest中添加属性,替换属性,移除属性的事件监听器。
2.示例(以ServletRequestAttributeListener为例):
(1).监听器如下:
public class TestAttributeListener implements ServletRequestAttributeListener {
    //添加属性时被调用
    @Override
    public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("向request中添加了一个属性");
    }
    //移除属性时被调用
    @Override
    public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("从request中移除了一个属性");
    }
    //替换属性时被调用
    @Override
    public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("从request中属性替换了");
    }
}
(2).被触发:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <%
        <!-- 触发attributeAdded-->
        request.setAttribute("name","aaa");
        <!-- 触发attributeReplaced-->
        request.setAttribute("name","aa");
        <!-- 触发attributeRemoved-->
        request.removeAttribute("name");
    %>
</body>
</html>

3.API

对于方法内的XxxAttributeEvent对象
有两个方法:
getName():获取属性的名字
getValue():获取属性的值。


5.感知Session绑定的事件监听器

1.概述

1.保存在Session域中的对象可以有多种状态

(1).绑定到session中
(2).从Session域中解除绑定
(3).随Session对象持久化到一个存储设备中

(4).随Session对象从一个存储设备中恢复
2.Servlet规范中定义了两个特殊的监听器来帮助JavaBean对象了解自己在Session域中的这些状态

HttpSessionBindingListener接口
HttpSessionActivationListener接口
注意:实现这两个接口的类不需要在web.xml中进行注册。

2.HttpSessionBindingListener接口

1.概述

(1).实现了HttpSessionBindingListener接口的JavaBean对象可以感知自己被绑定到Session中和从Session中删除的事件。
(2).当对象被绑定到HttpSession对象中时,WEB服务器调用该对象的void valueBound(HttpSessionBindingEvent event)方法
(3).当对象从HttpSession对象中解除绑定时,WEB服务器调用该对象的void valueUnbound(HttpSessionBindingEvent event)方法

2.关于该接口两个API中的参数(HttpSessionBindingEvent对象)

该对象有3个方法:
(1).getValue():获取属性名
(2).getName():获取属性值
(3).getSession():获取该session

3.示例:
(1).实现类:
package aaa;

import com.sun.jmx.snmp.SnmpUnknownSubSystemException;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionEvent;
import java.io.Serializable;

public class Customer implements HttpSessionBindingListener {
    
    @Override
    public void valueBound(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("绑定到Session");
        Object value = httpSessionBindingEvent.getValue();

        System.out.println(value );
        System.out.println(httpSessionBindingEvent.getSession());
        System.out.println(httpSessionBindingEvent.getName());
    }
    @Override
    public void valueUnbound(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("从session中解除绑定");
    }

}

(2).jsp中:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="aaa.Customer" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <%
        Customer customer = new Customer();
        session.setAttribute("cus",customer);
    %>
</body>
</html>

3.HttpSessionActivationListener接口

1.概述

(1).实现了该接口和Serializable接口的JavaBean对象可以感知自己被活化(从磁盘上读取session对象到内存)和钝化(从内存写入session对象到磁盘上)的事件。
(2).当绑定到HttpSession对象中的对象将要随HttpSession对象被钝化之前,WEB服务器调用该对象的void sessionWillPassivate(HttpSessionBindingEvent event)方法。
(3).当绑定到HttpSession对象中的对象将要随HttpSession对象被活化之后,WEB服务器调用该对象的void sessionDidActive(HttpSessionBindingEvent event)方法
注意:该监听器不需要在web.xml中配置

2.接口实现类的方法中的参数(HttpSessionEvent)

只有一个方法
getSession();

3.示例
(1).实现类中:

public class Customer implements HttpSessionActivationListener , Serializable {
    //在钝化之前被调用
    @Override
    public void sessionWillPassivate(HttpSessionEvent httpSessionEvent) {
        System.out.println("写入磁盘");
    }
    //在活化之后被调用
    @Override
    public void sessionDidActivate(HttpSessionEvent httpSessionEvent) {
        System.out.println("从磁盘中读取");
    }
}
(2).jsp中:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="aaa.Customer" %>
<%@ page import="org.omg.PortableInterceptor.SYSTEM_EXCEPTION" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <%
        Object customer = session.getAttribute("customer");
        if (customer == null){
            System.out.println("创建一个新的对象,并放入到session中");
            Customer customer1 = new Customer();
            session.setAttribute("customer",customer1);
        }else{
            System.out.println("从session中读取到customer对象:" + customer);
        }
    %>
</body>
</html>
上一篇下一篇

猜你喜欢

热点阅读