一,监听器介绍

监听器是一个专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时,立即采取相应的行动。监听器其实就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法立即被执行。

监听器的相关概念:

事件源

被监听的对象

监听器

监听事件源对象,事件源对象的状态的变化都会触发监听器

注册监听器

将监听器与事件源进行绑定。

响应行为

监听器监听到事件源的状态变化时 所涉及的功能代码。

二,监听器的分类

分类1:按照被监听的对象划分

ServletRequest域

HttpSession域

ServletContext域

分类2:监听的内容分

监听域对象的创建与销毁的

监听域对象的属性变化的

三,监听三大域对象的创建与销毁的监听器

监听器的编写步骤:

1、编写一个监听器类去实现监听器接口

2、覆盖监听器的方法

3、需要在web.xml中进行配置

1,监听ServletContext域的创建与销毁的监听器ServletContextListener

当ServletContext对象被创建时,触发contextInitialized (ServletContextEvent arg0)方法。

当ServletContext对象被销毁时,触发contextDestroyed(ServletContextEvent arg0)方法。

ServletContext域对象创建和销毁时机:

创建:服务器启动针对每一个Web应用创建ServletContext。

销毁:服务器关闭前先关闭代表每一个web应用的ServletContext。

例如:

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
 
public class MyServletContextListener implements ServletContextListener{
 
@Override
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println("ServletContext对象销毁了!");
}
 
@Override
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("ServletContext对象创建了!");
}
}

在web.xml文件中注册监听器:

<?xml version="1.0" encoding="UTF-8"?>
<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"
id="WebApp_ID" version="3.0">
<display-name>Listener</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 注册针对ServletContext对象的监听器 -->
<listener>
<listener-class>com.zender.MyServletContextListener</listener-class>
</listener>
</web-app>

web服务器启动:

web服务器关闭:

2,监听Httpsession域的创建于销毁的监听器HttpSessionListener

当创建一个Session时,触发sessionCreated (HttpSessionEvent arg0) 方法

当销毁一个Session时,触发sessionDestroyed (HttpSessionEvent arg0) 方法。

Httpsession域对象创建和销毁时机:

创建:第一次调用request.getSession时创建。

销毁:服务器关闭销毁 session过期 手动销毁。

例如:

import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
 
public class MyHttpSessionListener implements HttpSessionListener {
 
@Override
public void sessionCreated(HttpSessionEvent arg0) {
System.out.println("session创建:" + arg0.getSession().getId());
}
 
@Override
public void sessionDestroyed(HttpSessionEvent arg0) {
System.out.println("session销毁了!");
}
}

在web.xml文件中注册监听器:

<?xml version="1.0" encoding="UTF-8"?>
<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"
id="WebApp_ID" version="3.0">
<display-name>Listener</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 注册针对HttpSession对象的监听器 -->
<listener>
<listener-class>com.zender.MyHttpSessionListener</listener-class>
</listener>
</web-app>

访问页面时:

3,监听ServletRequest域创建与销毁的监听器ServletRequestListener

当Request对象被创建时,触发requestInitialized(ServletRequestEvent arg0)方法。

当Request对象被销毁时,触发requestDestroyed(ServletRequestEvent arg0)方法。

ServletRequest域对象创建和销毁时机:

创建:用户每一次访问都会创建request对象

销毁:当前访问结束,request对象就会销毁

例如:

import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
 
public class MyServletRequestListener implements ServletRequestListener {
 
@Override
public void requestDestroyed(ServletRequestEvent arg0) {
System.out.println("request对象销毁了");
}
 
@Override
public void requestInitialized(ServletRequestEvent arg0) {
System.out.println("request对象创建了");
}
}

在web.xml文件中注册监听器:

<?xml version="1.0" encoding="UTF-8"?>
<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"
id="WebApp_ID" version="3.0">
<display-name>Listener</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 注册针对Request对象的监听器 -->
<listener>
<listener-class>com.zender.MyServletRequestListener</listener-class>
</listener>
</web-app>

访问页面时:

可以看出用户每一次访问都会创建request对象,当访问结束后,request对象就会销毁。

四.监听三大域对象的属性变化的监听器

1,监听ServletContext域的属性变化的监听器ServletContextAttributeListener

当ServletContext对象添加属性时,触发attributeAdded(ServletContextAttributeEvent arg0)方法。

当ServletContext对象修改属性时,触发attributeReplaced(ServletContextAttributeEvent arg0)方法。

当ServletContext对象删除属性时,触发attributeRemoved(ServletContextAttributeEvent arg0)方法。

例如:

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
 
public class MyServletContextAttributeListener implements ServletContextAttributeListener {
 
@Override
public void attributeAdded(ServletContextAttributeEvent arg0) {
System.out.println("属性被添加,name:" + arg0.getName() + "value:" + arg0.getValue());
}
 
@Override
public void attributeRemoved(ServletContextAttributeEvent arg0) {
System.out.println("属性被删除,name:" + arg0.getName() + "value:" + arg0.getValue());
}
 
@Override
public void attributeReplaced(ServletContextAttributeEvent arg0) {
//获得是修改前的数据
System.out.println("属性被修改,name:" + arg0.getName() + "value:" + arg0.getValue());
}
}

Servlet:

import java.io.IOException;
 
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
public class TestMyServletContextAttributeListener extends HttpServlet{ private static final long serialVersionUID = -7057319189693064505L; @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
//存储一个数据
context.setAttribute("name", "Zender");
//修改一个数据
context.setAttribute("name", "Zender2");
//删除一个数据
context.removeAttribute("name");
}
}

在web.xml文件中注册监听器和Servlet:

<?xml version="1.0" encoding="UTF-8"?>
<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"
id="WebApp_ID" version="3.0">
<display-name>Listener</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list> <!-- 注册Servlet -->
<servlet>
<servlet-name>TestMyServletContextAttributeListener</servlet-name>
<servlet-class>com.zender.servlet.TestMyServletContextAttributeListener</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TestMyServletContextAttributeListener</servlet-name>
<url-pattern>/index.html</url-pattern>
</servlet-mapping> <!-- 注册针对ServletContext对象的属性的监听器 -->
<listener>
<listener-class>com.zender.MyServletContextAttributeListener</listener-class>
</listener>
</web-app>

访问http://localhost:8081/Listener/index.html,后台结果:

2, HttpSessionAttributeListener监听器(同上)

3,ServletRequestAriibuteListenr监听器(同上)

五,与session中的绑定的对象相关的监听器(对象感知监听器)

即将要被绑定到session中的对象有4种状态:

绑定状态

就一个对象被放到session域中

解绑状态

就是这个对象从session域中移除了

钝化状态

是将session内存中的对象持久化(序列化)到磁盘

活化状态

就是将磁盘上的对象再次恢复到session内存中

1,绑定与解绑的监听器HttpSessionBindingListener

当Person类在HttpSession对象绑定属性时,触发valueBound(HttpSessionBindingEvent arg0)方法。

当Person类在HttpSession对象解绑属性时,触发valueUnbound(HttpSessionBindingEvent arg0)方法。

例如:

首先创建一个Person类实现HttpSessionBindingListener接口:

    public class Person implements HttpSessionBindingListener {
private int id;
private String name;
public int getId() {
return id;
} public Person(int id, String name) {
this.id = id;
this.name = name;
}
public Person() {
} public void setId(int id) {
this.id = id;
}
 
public String getName() {
return name;
}
 
public void setName(String name) {
this.name = name;
}
 
@Override
public void valueBound(HttpSessionBindingEvent arg0) {
System.out.println("person对象被绑定了!");
}
 
@Override
public void valueUnbound(HttpSessionBindingEvent arg0) {
System.out.println("person对象被解绑了!");
}
}

Servlet:

import java.io.IOException;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
 
import com.zender.Person;
 
public class TestPersonBindingListener extends HttpServlet {
 
private static final long serialVersionUID = -4836536065640905707L; @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
//将Person绑定到Session域中
session.setAttribute("persion", new Person(1,"Zender"));
//将Person从Session域中解绑
session.removeAttribute("persion");
}
}

在web.xml文件中注册Servlet:

<?xml version="1.0" encoding="UTF-8"?>
<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"
id="WebApp_ID" version="3.0">
<display-name>Listener</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list> <!-- 注册Servlet -->
<servlet>
<servlet-name>TestPersonBindingListener</servlet-name>
<servlet-class>com.zender.servlet.TestPersonBindingListener</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TestPersonBindingListener</servlet-name>
<url-pattern>/index.html</url-pattern>
</servlet-mapping>
</web-app>

访问http://localhost:8081/Listener/index.html,后台结果:

2,钝化与活化的监听器HttpSessionActivationListener

当Person类被钝化时,触发sessionWillPassivate(HttpSessionEvent arg0)方法。

当Person类被活化时,触发sessionDidActivate(HttpSessionEvent arg0)方法。

例如:

首先创建一个Person类实现HttpSessionActivationListener接口,并且这个类必须实现Serializable接口(序列化):

public class Person implements HttpSessionActivationListener,Serializable{
private int id;
private String name;
public int getId() {
return id;
} public Person(int id, String name) {
this.id = id;
this.name = name;
}
public Person() {
} public void setId(int id) {
this.id = id;
}
 
public String getName() {
return name;
}
 
public void setName(String name) {
this.name = name;
}
 
@Override
public void sessionDidActivate(HttpSessionEvent arg0) {
System.out.println("Person被活化了");
}
 
@Override
public void sessionWillPassivate(HttpSessionEvent arg0) {
System.out.println("Person被钝化了");
}
}

Servlet:

import java.io.IOException;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
 
import com.zender.Person;
 
public class TestPersonActivationListener extends HttpServlet {
 
private static final long serialVersionUID = -4836536065640905707L; @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
//将Person绑定到Session域中
session.setAttribute("persion", new Person(1,"Zender"));
System.out.println("Person被放到Session域中了!");
}
}

在web.xml文件中注册Servlet:

<?xml version="1.0" encoding="UTF-8"?>
<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"
id="WebApp_ID" version="3.0">
<display-name>Listener</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list> <!-- 注册Servlet -->
<servlet>
<servlet-name>TestPersonActivationListener</servlet-name>
<servlet-class>com.zender.servlet.TestPersonActivationListener</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TestPersonActivationListener</servlet-name>
<url-pattern>/index.html</url-pattern>
</servlet-mapping>
</web-app>

访问http://localhost:8081/Listener/index.html,后台结果:

关闭服务器:

控制台打印:

钝化的文件:

活化对象:

Servlet2:

import java.io.IOException;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
 
import com.zender.Person;
 
public class TestPersonActivationListener2 extends HttpServlet {
 
private static final long serialVersionUID = -4836536065640905707L; @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
//获取Session域中的Person
Person p = (Person) session.getAttribute("persion");
System.out.println("name:" + p.getName());
}
}

在web.xml文件中注册Servlet2:

    <!-- 注册Servlet -->
<servlet>
<servlet-name>TestPersonActivationListener2</servlet-name>
<servlet-class>com.zender.servlet.TestPersonActivationListener2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TestPersonActivationListener2</servlet-name>
<url-pattern>/index2.html</url-pattern>
</servlet-mapping>

启动服务器自动活化对象:

访问:http://localhost:8081/Listener/index2.html,控制台打印:

怎么控制对象的钝化时间呢?可以通过配置文件,指定对象钝化时间,对象多长时间不用会被钝化。

在META-INF下创建一个context.xml

内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<Context>
<!-- 这样session在一分钟不动的情况下则会被钝化到tomcat工作目录下面的 cjq目录下,直到再次访问才被激活。 -->
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
<Store className="org.apache.catalina.session.FileStore" directory="cjq" />
</Manager>
</Context>

启动服务器访问Servlet把对象放到Session中:

控制台:过1分钟后对象会被自动钝化:

钝化的文件:

访问Servlet2时,对象会自动被活化:

Java Web学习总结(13)Listener监听器的更多相关文章

  1. java web学习总结(二十) -------------------监听器属性详解

    一.监听域对象中属性的变更的监听器 域对象中属性的变更的事件监听器就是用来监听 ServletContext, HttpSession, HttpServletRequest 这三个对象中的属性变更信 ...

  2. java web学习总结(十九) -------------------监听器简单使用场景

    一.统计当前在线人数 在JavaWeb应用开发中,有时候我们需要统计当前在线的用户数,此时就可以使用监听器技术来实现这个功能了. 1 package me.gacl.web.listener; 2 3 ...

  3. [原创]java WEB学习笔记13:JSP介绍(背景,特点,原理)

    JSP介绍:(理解) 1)JSP背景 ①在很多动态网页中,绝大部分内容都是固定不变的,只有局部内容需要动态产生和改变: ②如果使用Servlet程序来输出只有局部内容需要动态改变的网页,其中所有的静态 ...

  4. [原创]java WEB学习笔记75:Struts2 学习之路-- 总结 和 目录

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  5. Java Web 学习笔记 1

    Java Web 学习笔记 1 一.Web开发基础 1-1 Java Web 应用开发概述 1.1.1 C/S C/S(Client/Server)服务器通常采用高性能的PC机或工作站,并采用大型数据 ...

  6. Java Web 学习路线

    实际上,如果时间安排合理的话,大概需要六个月左右,有些基础好,自学能力强的朋友,甚至在四个月左右就开始找工作了.大三的时候,我萌生了放弃本专业的念头,断断续续学 Java Web 累计一年半左右,总算 ...

  7. [原创]java WEB学习笔记95:Hibernate 目录

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  8. Java Web学习系列——Maven Web项目中集成使用Spring、MyBatis实现对MySQL的数据访问

    本篇内容还是建立在上一篇Java Web学习系列——Maven Web项目中集成使用Spring基础之上,对之前的Maven Web项目进行升级改造,实现对MySQL的数据访问. 添加依赖Jar包 这 ...

  9. Java Web学习系列——Maven Web项目中集成使用Spring

    参考Java Web学习系列——创建基于Maven的Web项目一文,创建一个名为LockMIS的Maven Web项目. 添加依赖Jar包 推荐在http://mvnrepository.com/.h ...

  10. Java web 学习之旅

    java web学习之旅 来公司十天了,感觉已经慢慢地融入了这个环境中,几个学长人都很好,都是在他们帮助下,我才能比较顺利的开始了学习java web的旅途. 来这里学习的第一个阶段是做一个简单的用户 ...

随机推荐

  1. yii2框架的安装&配置启动

    top:环境MacBook 1.通过composer 安装yii2 [yii2需要php的PDO和pdo_mysql扩展,需要确认已安装] a. 首先需要配置composer:我使用的是阿里云的镜像: ...

  2. android7.0对于SharedPreferences设置模式的限制

    错误信息: 03-28 10:16:12.701   830   932 E AndroidRuntime: FATAL EXCEPTION: Thread-903-28 10:16:12.701   ...

  3. nginx配置多个虚拟主机(mac)

    1 . 安装  通过homebrew安装nginx,默认安装在:/usr/local/Cellar/nginx/版本号.配置文件在路径:/usr/local/etc/nginx ,默认配置文件ngin ...

  4. C++输出字符指针指向的地址

    int main() { char *s2 = "jwdajkj"; ]; )); printf("%p,%p\n", s3, s1); cout <&l ...

  5. Python程序打包为可执行文件exe

    Python程序打包为可执行文件exe,pyinstaller应用 山重水复疑无路,柳暗花明又一村. 本来是向老师提交一个python程序,因为第一次所以就很尴尬只把源码给老师了,应该是打包成一个可执 ...

  6. 工作笔记:phpstrom、docker、phpunit进行单元测试

  7. tensorflow 之Dataset数据集之批量数据

    ###生成批次数据 import tensorflow as tf '''reapt()生成重复数据集 batch()将数据集按批次组合''' file_name = ['img1','img2',' ...

  8. IOS-swift5.1快速入门之旅

    快速之旅 传统表明,新语言中的第一个程序应在屏幕上打印“Hello,world!”字样.在Swift中,这可以在一行中完成: print("Hello, world!") // P ...

  9. 简单的C++11线程池实现

    线程池的C++11简单实现,源代码来自Github上作者progschj,地址为:A simple C++11 Thread Pool implementation,具体博客可以参见Jakob's D ...

  10. vscode内置c++ define选项

    https://stackoverflow.com/questions/46415076/how-can-i-define-macros-for-the-c-intellisense-engine