Listener监听器

Listener监听器


1.基本概念

  • Servlet规范中定义的一种特殊的组件,用来监听Servlet容器产生的事件并进行相应的处理。 
  • 容器产生的事件分类如下:
  •               生命周期相关的事件。
  •               属性状态相关的事件。
  •               存值状态相关的事件。
  • 底层原理是采用接口回调的方式实现。

2.基本分类

监听器类型

功能介绍

javax.servlet.ServletRequestListener

监听request作用域的创建和销毁

javax.servlet.ServletRequestAttributeListener

监听request作用域的属性状态变化

javax.servlet.http.HttpSessionListener

监听session作用域的创建和销毁

javax.servlet.http.HttpSessionAttributeListener

监听session作用域的属性状态变化

javax.servlet.ServletContextListener

监听application作用域的创建和销毁

javax.servlet.ServletContextAttributeListener

监听application作用域的属性状态变化

javax.servlet.http.HttpSessionBindingListener

监听对象与session的绑定和解除

javax.servlet.http.HttpSessionActivationListener

监听session数值的钝化和活化

3.监听器详解

(1)ServletRequestListener监听器

ServletRequest创建和关闭时都会通知ServletRequestListener监听器

常用方法如下:

方法声明

功能介绍

void requestInitialized(ServletRequestEvent sre)

实现ServletRequest对象的初始化

void requestDestroyed(ServletRequestEvent sre)

实现ServletRequest对象的销毁

package com.lagou.demo03;

import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;

public class MyRequestListener implements ServletRequestListener {
    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
        System.out.println("请求销毁了...");
    }

    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
        System.out.println("创建请求...");
    }
}
<listener>
        <listener-class>com.lagou.demo03.MyRequestListener</listener-class>
    </listener>

(2)ServletRequestAttributeListener监听器

ServletRequest添加、删除或者替换一个属性的时候,将会通知ServletRequestAttributeListener监听器

常用方法如下:

方法声明

功能介绍

void attributeAdded(ServletRequestAttributeEvent srae)

增加属性时触发

void attributeReplaced(ServletRequestAttributeEvent srae)

修改属性时触发

void attributeRemoved(ServletRequestAttributeEvent srae)

删除属性时触发

package com.lagou.demo03;

import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;

public class MyRequestAttributeListener implements ServletRequestAttributeListener {
    @Override
    public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("增加了属性" + servletRequestAttributeEvent.getName());
    }

    @Override
    public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("属性" + servletRequestAttributeEvent.getName() + "被删除了" );
    }

    @Override
    public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("修改属性" + servletRequestAttributeEvent.getName());
    }
}
<listener>
        <listener-class>com.lagou.demo03.MyRequestAttributeListener</listener-class>
    </listener>

(3)HttpSessionListener监听器

当一个HttpSession刚被创建或者失效(invalidate)的时候,将会通知HttpSessionListener监听

常用方法如下:

方法声明

功能介绍

void sessionCreated(HttpSessionEvent se)

当一个HttpSession对象被创建时会调用这个方法

void sessionDestroyed(HttpSessionEvent se)

当一个HttpSession超时或者调用HttpSession

invalidate()方法让它销毁时,将会调用这个方法

package com.lagou.demo03;

import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class MySessionListener implements HttpSessionListener {
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        System.out.println("创建了session...");
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        System.out.println("session销毁!");
    }
}
<listener>
        <listener-class>com.lagou.demo03.MySessionListener</listener-class>
    </listener>

(4)HttpSessionAttributeListener监听器

HttpSession中添加、删除或者替换一个属性的时候,将会通知HttpSessionAttributeListener监  听器

常用方法如下:

方法声明

功能介绍

void attributeAdded(HttpSessionBindingEvent se)

当往会话中加入一个属性的时候会调用这个方法

void attributeRemoved(HttpSessionBindingEvent se)

当从会话中删除一个属性的时候会调用这个方法

void attributeReplaced(HttpSessionBindingEvent se)

当改变会话中的属性的时候会调用这个方法

package com.lagou.demo03;

import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;

public class MySessionAttributeListener implements HttpSessionAttributeListener {
    @Override
    public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("增加了属性" + httpSessionBindingEvent.getName());
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("属性" + httpSessionBindingEvent.getName() + "被删除!");
    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("修改属性" + httpSessionBindingEvent.getName());
    }
}
<listener>
        <listener-class>com.lagou.demo03.MySessionAttributeListener</listener-class>
    </listener>

(5)ServletContextListener监听器

ServletContext创建和关闭时都会通知ServletContextListener监听器

常用方法如下:

方法声明

功能介绍

void contextInitialized(ServletContextEvent sce)

ServletContext创建的时候,将会调用这个方法

void contextDestroyed(ServletContextEvent sce)

ServletContext销毁的时候(例如关闭应用服务器或者重新加载应用),将会调用这个方法

package com.lagou.demo03;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class MyContextListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println("ServletContext对象创建了...");
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println("销毁ServletContext对象...");
    }
}
<listener>
        <listener-class>com.lagou.demo03.MyContextListener</listener-class>
    </listener>

(6)ServletContextAttributeListener监听器

ServletContext添加、删除或者替换一个属性的时候,将会通知ServletContextAttributesListener监听器

常用方法如下:

方法声明

功能介绍

void attributeAdded(ServletContextAttributeEvent scae)

ServletContext中加入一个属性的时候触发

void attributeRemoved(ServletContextAttributeEvent scae)

ServletContext中删除一个属性的时候触发

void attributeReplaced(ServletContextAttributeEvent scae)

改变ServletContext中属性的时候触发

package com.lagou.demo03;

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;

public class MyContextAttributeListener implements ServletContextAttributeListener {
    @Override
    public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("增加了属性" + servletContextAttributeEvent.getName());
    }

    @Override
    public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("属性" + servletContextAttributeEvent.getName() + "被删除!");
    }

    @Override
    public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("修改属性" + servletContextAttributeEvent.getName());
    }
}
<listener>
        <listener-class>com.lagou.demo03.MyContextAttributeListener</listener-class>
    </listener>

(7)HttpSessionBindingListener监听器

HttpSession中绑定和解除绑定时,将会通知HttpSessionListener监听器

常用方法如下:

方法声明

功能介绍

void valueBound(HttpSessionBindingEvent event)

有对象绑定时调用该方法

void valueUnbound(HttpSessionBindingEvent event)

有对象解除绑定时调用该方法

package com.lagou.demo03;

import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

public class Person implements HttpSessionBindingListener {
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public void valueBound(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("对象绑定到session中了" + httpSessionBindingEvent.getName());
    }

    @Override
    public void valueUnbound(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("解除绑定成功!");
    }
}
<%@ page import="com.lagou.demo03.Person" %><%--
  Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>实现session中对象的绑定和解除</title>
</head>
<body>
<%
    // 准备一个Person类型的对象
    Person person = new Person();
    person.setName("zhangfei");
    person.setAge(30);
    // 将对象与session对象进行绑定
    session.setAttribute("person", person);
    // 解除绑定
    session.removeAttribute("person");
%>
</body>
</html>

(8)HttpSessionActivationListener监听器

当有session数值的钝化和活化操作时,将会通知HttpSessionActivationListener监听器

常用方法如下:

方法声明

功能介绍

void sessionWillPassivate(HttpSessionEvent se)

有钝化操作时调用该方法

void sessionDidActivate(HttpSessionEvent se)

有活化操作时调用该方法

package com.lagou.demo03;

import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionEvent;
import java.io.Serializable;

public class Student implements Serializable, HttpSessionActivationListener {
    private String name;

    public Student() {
    }

    public Student(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                '}';
    }

    @Override
    public void sessionWillPassivate(HttpSessionEvent httpSessionEvent) {
        System.out.println("执行了钝化操作..." + httpSessionEvent.getSession());
    }

    @Override
    public void sessionDidActivate(HttpSessionEvent httpSessionEvent) {
        System.out.println("活化操作进行中...");
    }
}
<%--
  Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>实现session中数据的获取</title>
</head>
<body>
<%
    Object student = session.getAttribute("student");
    System.out.println("获取到的数据为:" + student);
%>
</body>
</html>

活化操作时,需要将session从硬盘中读取到内存中,但IDEA会默认在启动时从硬盘中删除保存的session,所以应该将配置context.xml文件的增加如下内容:

<Manager className="org.apache.catalina.session.PersistentManager" saveOnRestart="true">
<!-- 配置文件存放的路径信息,可以自由指定 -->
<Store className="org.apache.catalina.session.FileStore" directory="C:\session"/>
</Manager>

案例:实现网站在线人数的统计(比如增加在线人数)

package com.lagou.demo04;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class OnlineUser implements HttpSessionListener, ServletContextListener {
    // 声明一个ServletContex类型的引用负责作为全局对象来记录当前在线用户的数量,通过属性记录
    private ServletContext servletContext = null;

    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        servletContext = servletContextEvent.getServletContext();
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        servletContext = null;
    }

    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        System.out.println("有新用户上线了...");
        Object count = servletContext.getAttribute("count");
        // 若当前用户为第一个用户,则将全局对象中的属性值设置为1即可
        if (null == count) {
            servletContext.setAttribute("count", 1);
        }
        // 若当前用户不是第一个用户,则将全局对象中原有的数据取出来加1后再设置进去
        else {
            Integer integer = (Integer)count;
            integer++;
            servletContext.setAttribute("count", integer);
        }
        System.out.println("当前在线用户数量为:" + servletContext.getAttribute("count"));
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        System.out.println("有用户已下线...");
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    
    <listener>
        <listener-class>com.lagou.demo04.OnlineUser</listener-class>
    </listener>
</web-app>
<%--
  Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>实现当前在线的用户数量</title>
</head>
<body>
<h1>当前在线用户人数为:${applicationScope.count}</h1>
</body>
</html>

节选自拉钩教育JAVA系列课程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值