博客
关于我
Listener监听器
阅读量:355 次
发布时间:2019-03-04

本文共 7394 字,大约阅读时间需要 24 分钟。

基本概念

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

基本分类

Listener监听三个域对象创建与销毁

ServletRequestListener监听器
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("创建请求...");    }}

在web.xml文件中配置监听器。

com.lagou.demo03.MyRequestListener
HttpSessionListener监听器
ServletContextListener监听器

Listener监听三个域对象属性状态的改变

ServletRequestAttributeListener监听器

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

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());    }}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>    实现请求中属性状态的改变<%    // 实现属性的添加    request.setAttribute("name", "zhangfei");    // 实现属性的修改    request.setAttribute("name", "guanyu");    // 实现属性的删除    request.removeAttribute("name");%>

在web.xml文件中配置监听器。

com.lagou.demo03.MyRequestAttributeListener
HttpSessionAttributeListener监听器
ServletContextAttributeListener监听器

Listener监听HttpSession域对象存值的状态变更

这两种监听器不用配置(注册)。

HttpSessionBindingListener监听器

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

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" %>    实现session中对象的绑定和解除<%    // 准备一个Person类型的对象    Person person = new Person();    person.setName("zhangfei");    person.setAge(30);    // 将对象与session对象进行绑定    session.setAttribute("person", person);    // 解除绑定    session.removeAttribute("person");%>
HttpSessionActivationListener监听器

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

  • 可以理解为序列化操作:将一个对象的所有数据内容转换成字节序列

session的钝化活化的用意:

  • session中的值可能会很多,并且我们有很长一段时间不会去使用这个内存中的值,那么可以考虑把session中的值存储到硬盘上(钝化),等下一次要使用的时候,从硬盘上提取到内存中(活化)

  • 停止服务器时会执行钝化操作

  • 启动服务器时会执行活化操作

    • IDEA重启时会把tomcat的work目录下的内容删掉重新生成,存在该目录下的被钝化的数据被删除,此时无法活化

    • 改配置文件context.xml,更改存储位置

      directory="C:\session"要确保该目录存在,没有就手动创建

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("活化操作进行中...");    }}

钝化:

<%@ page import="com.lagou.demo03.Student" %><%--  Created by IntelliJ IDEA.--%><%@ page contentType="text/html;charset=UTF-8" language="java" %>    实现session中数据的钝化和活化操作<%    // 创建Student类型的对象    Student student = new Student();    student.setName("zhangfei");    // 将数据放入到session中    session.setAttribute("student", student);%>

活化:

<%--  Created by IntelliJ IDEA.--%><%@ page contentType="text/html;charset=UTF-8" language="java" %>    实现session中数据的获取<%    Object student = session.getAttribute("student");    System.out.println("获取到的数据为:" + student);%>

实战案例

自定义类实现监听器接口并重写相关的方法。

例:记录当前在线用户数

session:浏览器向服务器发送一个请求,服务器就会创建一个session对象,即有多少个用户访问就有多少个session

ServletContext:一个web项目只对应一个

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("有用户已下线...");    }}

在web.xml中配置监听器

com.lagou.demo04.OnlineUser

测试功能

<%--  Created by IntelliJ IDEA.--%><%@ page contentType="text/html;charset=UTF-8" language="java" %>    实现当前在线的用户数量

当前在线用户人数为:${applicationScope.count}

转载地址:http://gune.baihongyu.com/

你可能感兴趣的文章
MySql中关于geometry类型的数据_空的时候如何插入处理_需用null_空字符串插入会报错_Cannot get geometry object from dat---MySql工作笔记003
查看>>
mysql中出现Incorrect DECIMAL value: '0' for column '' at row -1错误解决方案
查看>>
mysql中出现Unit mysql.service could not be found 的解决方法
查看>>
mysql中出现update-alternatives: 错误: 候选项路径 /etc/mysql/mysql.cnf 不存在 dpkg: 处理软件包 mysql-server-8.0的解决方法(全)
查看>>
Mysql中各类锁的机制图文详细解析(全)
查看>>
MySQL中地理位置数据扩展geometry的使用心得
查看>>
Mysql中存储引擎简介、修改、查询、选择
查看>>
Mysql中存储过程、存储函数、自定义函数、变量、流程控制语句、光标/游标、定义条件和处理程序的使用示例
查看>>
mysql中实现rownum,对结果进行排序
查看>>
mysql中对于数据库的基本操作
查看>>
Mysql中常用函数的使用示例
查看>>
MySql中怎样使用case-when实现判断查询结果返回
查看>>
Mysql中怎样使用update更新某列的数据减去指定值
查看>>
Mysql中怎样设置指定ip远程访问连接
查看>>
mysql中数据表的基本操作很难嘛,由这个实验来带你从头走一遍
查看>>
Mysql中文乱码问题完美解决方案
查看>>
mysql中的 +号 和 CONCAT(str1,str2,...)
查看>>
Mysql中的 IFNULL 函数的详解
查看>>
mysql中的collate关键字是什么意思?
查看>>
MySql中的concat()相关函数
查看>>