监听器高级学习

一、监听域对象中属性的变更的监听器

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

1.1、attributeAdded 方法

  当向被监听对象中增加一个属性时,web容器就调用事件监听器的attributeAdded方法进行响应,这个方法接收一个事件类型的参数,监听器可以通过这个参数来获得正在增加属性的域对象和被保存到域中的属性对象
  各个域属性监听器中的完整语法定义为:

public void attributeAdded(ServletContextAttributeEvent scae)
public void attributeReplaced(HttpSessionBindingEvent  hsbe)
public void attributeRmoved(ServletRequestAttributeEvent srae)

1.2、attributeRemoved 方法

  当删除被监听对象中的一个属性时,web容器调用事件监听器的attributeRemoved方法进行响应
  各个域属性监听器中的完整语法定义为:

public void attributeRemoved(ServletContextAttributeEvent scae)
public void attributeRemoved (HttpSessionBindingEvent  hsbe)
public void attributeRemoved (ServletRequestAttributeEvent srae)

1.3、attributeReplaced 方法

  当监听器的域对象中的某个属性被替换时,web容器调用事件监听器的attributeReplaced方法进行响应
  各个域属性监听器中的完整语法定义为:

 public void attributeReplaced(ServletContextAttributeEvent scae)
 public void attributeReplaced (HttpSessionBindingEvent  hsbe)
 public void attributeReplaced (ServletRequestAttributeEvent srae)

1.4、ServletContextAttributeListener监听器范例:

  编写ServletContextAttributeListener监听器监听ServletContext域对象的属性值变化情况,代码如下:

public class MyServletContextAttributeListener implements ServletContextAttributeListener {

    @Override
    public void attributeAdded(ServletContextAttributeEvent scab) {
        String str =MessageFormat.format(
                "ServletContext域对象中添加了属性:{0},属性值是:{1}"
                ,scab.getName()
                ,scab.getValue());
        System.out.println(str);
    }

    @Override
    public void attributeRemoved(ServletContextAttributeEvent scab) {
        String str =MessageFormat.format(
                "ServletContext域对象中删除属性:{0},属性值是:{1}"
                ,scab.getName()
                ,scab.getValue());
        System.out.println(str);
    }

    @Override
    public void attributeReplaced(ServletContextAttributeEvent scab) {
        String str =MessageFormat.format(
                "ServletContext域对象中替换了属性:{0}的值"
                ,scab.getName());
        System.out.println(str);
    }
}

ServletContextAttributeListenerTest.jsp

<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<html>
<head>
    <title>ServletContextAttributeListener监听器测试</title>
</head>

<body>
<%
    //往application域对象中添加属性
    application.setAttribute("name", "孤傲苍狼");
    //替换application域对象中name属性的值
    application.setAttribute("name", "gacl");
    //移除application域对象中name属性
    application.removeAttribute("name");
%>
</body>
</html>

1.5、ServletRequestAttributeListener和HttpSessionAttributeListener监听器范例:

  编写监听器监听HttpSession和HttpServletRequest域对象的属性值变化情况,代码如下:

public class MyRequestAndSessionAttributeListener implements
        HttpSessionAttributeListener, ServletRequestAttributeListener {
    @Override
    public void attributeAdded(ServletRequestAttributeEvent srae) {
        String str =MessageFormat.format(
                "ServletRequest域对象中添加了属性:{0},属性值是:{1}"
                ,srae.getName()
                ,srae.getValue());
        System.out.println(str);
    }

    @Override
    public void attributeRemoved(ServletRequestAttributeEvent srae) {
        String str =MessageFormat.format(
                "ServletRequest域对象中删除属性:{0},属性值是:{1}"
                ,srae.getName()
                ,srae.getValue());
        System.out.println(str);
    }

    @Override
    public void attributeReplaced(ServletRequestAttributeEvent srae) {
        String str =MessageFormat.format(
                "ServletRequest域对象中替换了属性:{0}的值"
                ,srae.getName());
        System.out.println(str);
    }

    @Override
    public void attributeAdded(HttpSessionBindingEvent se) {
        String str =MessageFormat.format(
                "HttpSession域对象中添加了属性:{0},属性值是:{1}"
                ,se.getName()
                ,se.getValue());
        System.out.println(str);
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent se) {
        String str =MessageFormat.format(
                "HttpSession域对象中删除属性:{0},属性值是:{1}"
                ,se.getName()
                ,se.getValue());
        System.out.println(str);
    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent se) {
        String str =MessageFormat.format(
                "HttpSession域对象中替换了属性:{0}的值"
                ,se.getName());
        System.out.println(str);
    }
}

RequestAndSessionAttributeListenerTest.jsp

<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<html>
<head>
    <title>RequestAndSessionAttributeListener监听器测试</title>
</head>

<body>
<%
    //往session域对象中添加属性
    session.setAttribute("aa", "bb");
    //替换session域对象中aa属性的值
    session.setAttribute("aa", "xx");
    //移除session域对象中aa属性
    session.removeAttribute("aa");

    //往request域对象中添加属性
    request.setAttribute("aa", "bb");
    //替换request域对象中aa属性的值
    request.setAttribute("aa", "xx");
    //移除request域对象中aa属性
    request.removeAttribute("aa");
%>
</body>
</html>

二、感知Session绑定的事件监听器

  保存在Session域中的对象可以有多种状态:绑定(session.setAttribute("bean",Object))到Session中;从 Session域中解除(session.removeAttribute("bean"))绑定;随Session对象持久化到一个存储设备中;随Session对象从一个存储设备中恢复
  Servlet 规范中定义了两个特殊的监听器接口"HttpSessionBindingListener和HttpSessionActivationListener"来帮助JavaBean 对象了解自己在Session域中的这些状态: ,实现这两个接口的类不需要 web.xml 文件中进行注册

2.1、HttpSessionBindingListener接口

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

public class ListenerSession implements HttpSessionBindingListener{
    private String name;

    @Override
    public void valueBound(HttpSessionBindingEvent event) {
        System.out.println(name+"被加到session中了");
    }

    @Override
    public void valueUnbound(HttpSessionBindingEvent event) {
        System.out.println(name+"被session踢出来了");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public ListenerSession(String name) {
        this.name = name;
    }
}
HttpSessionBindingListener.jsp
<%@ page language="java" pageEncoding="UTF-8"%>
<%@page import=" com.java.web.SessionListener.ListenerSession"%>
<!DOCTYPE HTML>
<html>
<head>
    <title></title>
</head>

<body>
<%
    //将javabean对象绑定到Session中
    session.setAttribute("bean",new ListenerSession("孤傲苍狼"));
    //从Session中删除javabean对象
    session.removeAttribute("bean");
%>
</body>
</html>

2.2、HttpSessionActivationListener接口

  实现了HttpSessionActivationListener接口的JavaBean对象可以感知自己被活化(反序列化)和钝化(序列化)的事件
  当绑定到HttpSession对象中的javabean对象将要随HttpSession对象被钝化(序列化)之前,web服务器调用该javabean对象的void sessionWillPassivate(HttpSessionEvent event) 方法。这样javabean对象就可以知道自己将要和HttpSession对象一起被序列化(钝化)到硬盘中.
  当绑定到HttpSession对象中的javabean对象将要随HttpSession对象被活化(反序列化)之后,web服务器调用该javabean对象的void sessionDidActive(HttpSessionEvent event)方法。这样javabean对象就可以知道自己将要和 HttpSession对象一起被反序列化(活化)回到内存中

范例:

public class SessionActivationListener implements HttpSessionActivationListener, Serializable{
    private static final long serialVersionUID = 7589841135210272124L;
    private String name;

    @Override
    public void sessionWillPassivate(HttpSessionEvent se) {

        System.out.println(name+"和session一起被序列化(钝化)到硬盘了,session的id是:"+se.getSession().getId());
    }

    @Override
    public void sessionDidActivate(HttpSessionEvent se) {
        System.out.println(name+"和session一起从硬盘反序列化(活化)回到内存了,session的id是:"+se.getSession().getId());
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public SessionActivationListener(String name) {
        this.name = name;
    }
}
SessionActivationListener.jsp
<%@ page language="java" pageEncoding="UTF-8"%>
<%@page import="com.java.web.SessionListener.SessionActivationListener"%>
<!DOCTYPE HTML>
<html>
<head>
    <title></title>
</head>

<body>
一访问JSP页面,HttpSession就创建了,创建好的Session的Id是:${pageContext.session.id}
<hr/>
<%
    session.setAttribute("bean",new SessionActivationListener("孤傲苍狼"));
%>
</body>
</html>

最后的web.xml:

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
  <display-name>Archetype Created Web Application</display-name>

  <listener>
    <description>MyServletContextAttributeListener监听器</description>
    <listener-class>com.java.web.attributeListener.MyServletContextAttributeListener</listener-class>
  </listener>
  <listener>
    <description>MyRequestAndSessionAttributeListener监听器</description>
    <listener-class>com.java.web.attributeListener.MyRequestAndSessionAttributeListener</listener-class>
  </listener>
  <listener>
    <description>HttpSessionBindingListener监听器</description>
    <listener-class>com.java.web.SessionListener.ListenerSession</listener-class>
  </listener>
  <listener>
    <description>SessionActivationListener</description>
    <listener-class>com.java.web.SessionListener.SessionActivationListener</listener-class>
  </listener>

  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

转自: javaweb学习总结(四十五)——监听器(Listener)学习二

原文地址:https://www.cnblogs.com/heqiyoujing/p/9525961.html