Javaweb中的监听器Listener
servlet中的监听器
servlet中的监听器是用于监听web常见对象HttpServletRequest,HttpSession,ServletContext。主要有下面三个作用:
1.监听web对象创建与销毁。
2.监听web对象的属性变化,添加、删除、修改。
3.监听session绑定javaBean操作,活化(从硬盘读取到内存)与钝化(从内存持久化到硬盘)操作。
当监听器发现被监听的对象发生变化时,可以做一些操作。
在servlet中一共有8个监听器,按照监听器的作用分类如下:
- 监听web对象创建与销毁的监听器
- ServletContextListener
- HttpSessionListener
- ServletRequestListener
- 监听web对象属性变化的监听器
- ServletContextAttributeListener
- HttpSessionAttributeListener
- ServletRequestAttributeListener
- 监听session绑定javaBean操作的监听器
- HttpSessionBindingListener
- HttpSessionActivationListener
监听器的创建和使用
javaweb创建监听器的步骤:
- 创建一个类,实现指定的监听器接口
- 重写接口中的方法
- 在web.xml文件中配置监听器
监听对象的创建和销毁
下面演示监听HttpServletRequest对象的销毁和创建。
1.创建一个类实现ServletRequestListener接口:
ServletRequestListener接口 里面有两个 默认方法(Default),我们直接重写即可:
package jtq; import javax.servlet.ServletRequestEvent; import javax.servlet.ServletRequestListener; public class listener implements ServletRequestListener { @Override public void requestDestroyed(ServletRequestEvent sre) { System.out.println("Request 被我销毁了"); } @Override public void requestInitialized(ServletRequestEvent sre) { System.out.println("Request 生成了"); } }
在XML中配置监听器:
<listener> <listener-class>jtq.listener</listener-class> </listener>
记住这格式!
然后你就在你控制台看到你的 request 创建又销毁 来来回回的了...
同理,在监听HttpSesssion对象的创建与销毁时,需要创建一个类实现HttpSessionListener接口并重写里面的方法。【其他的都一样的啊! 直接实现重写然后配置!】即:
在监听ServletContext对象的创建与销毁时,创建一个类实现ServletContextListener接口并重写里面的方法即可。
什么情况下会销毁session:
- 默认超时 30分钟
- 关闭服务器
- invalidate()方法
- setMaxInactiveInterval(int interval) 可以设置超时时间
这个对象的监听就是这样的啊 具体其他自己去实现接口 重写 配置xml 即可。。。
这里他会检测全局【JSP 、 Servlet 都是....】
自己试试!!!
监听属性的变化
以监听在HttpServletRequest对象中添加、修改、删除属性为例:
其他的 session 啊 什么什么的 自己去用这种方式去试即可! 一定要动手:
首先 实现 HttpServletRequest 接口 然后我们重写他的方法【注释有解析】:
package Attribute; import javax.servlet.ServletRequestAttributeEvent; import javax.servlet.ServletRequestAttributeListener; public class Listeners_Attribute implements ServletRequestAttributeListener { @Override public void attributeAdded(ServletRequestAttributeEvent srae) { System.out.println("request 发生了变化 添加了" + srae.getName() + ", 他的值是:" + srae.getValue() ); } @Override public void attributeRemoved(ServletRequestAttributeEvent srae) { //删除reqeust属性时 触发 System.out.println("request 发生了变化 删除了" + srae.getName() + ", 他的值是:" + srae.getValue() ); } @Override public void attributeReplaced(ServletRequestAttributeEvent srae) { //修改reqeust属性时 触发 System.out.println("request 发生了变化 修改了" + srae.getName() + ", 他的值是:" + srae.getValue() ); } }
然后JSP页面写:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <% request.setAttribute("name", "bihu"); request.setAttribute("name","bihu-2"); request.removeAttribute("name"); %> </body> </html>
然后 web.XML 里面写:
<listener> <listener-class>Attribute.Listeners_Attribute</listener-class> </listener>
然后你可以看到:
request 发生了变化 修改了org.apache.catalina.ASYNC_SUPPORTED, 他的值是:true
request 发生了变化 添加了name, 他的值是:bihu
request 发生了变化 修改了name, 他的值是:bihu
request 发生了变化 删除了name, 他的值是:bihu-2
//我也不知道为什么第一个会冒出来,但我知道他是监听修改的出来的
其他的自己按照这个套路去试试!!! 这里不多说了!
这里他会检测全局的request【JSP 、 Servlet 都是....】的啊 就是 反正有 request 被改变 那么我就触发【这不就是 观察者模式吗 啊哈哈哈哈】
监听session绑定javabean
HttpSessionBindingListener监听器可以使javaBean对象在被绑定到会话或从会话中取消对它的绑定时得到通知。
该监听器是由实体类来实现,需要注意的是该监听器的实现类不需要在web.xml文件中进行配置(也可以配置 一般不用都可以)。
你可以在Eclipse 中 new 然后直接一个 监听器 然后实现 HttpSessionBindingListener 接口,且重写他的方法 然后添加你的set 和 get :
package Attribute; import javax.servlet.http.HttpSessionBindingEvent; import javax.servlet.http.HttpSessionBindingListener; /** * 自动监听器 * */ public class Student implements HttpSessionBindingListener { private String name; private int 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 void valueBound(HttpSessionBindingEvent event) { //绑定时 触发 System.out.println( event.getName() + "被Session绑定了(添加了)" ); } @Override public void valueUnbound(HttpSessionBindingEvent event) { //解绑时 触发 System.out.println( event.getName() + "被Session解绑了(删除了)" ); } }
然后新建一个 JSP 你就可以监听到 他是否被Session 绑定 和 解绑了:
<%@page import="Attribute.Student"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <% //这个为 测试类 JSP 当访问时 就会触发Student被绑定的事件 Student stu = new Student(); session.setAttribute("studnet", stu); session.removeAttribute("studnet"); %> <%-- 运行后你就会看到: studnet被Session绑定了(添加了) studnet被Session解绑了(删除了) --%> </body> </html>
监听在 Session 中存放的指定类型对象的钝化与活化(了解)
HttpSessionActivationListener该监听器用于监听在 Session 中存放的指定类型对象的钝化与活化。
钝化是指将内存中的数据写入到硬盘中,而活化是指将硬盘中的数据恢复到内存。当用
户正在访问的应用或该应用所在的服务器由于种种原因被停掉,然后在短时间内又重启,此时用户在访问时 Session 中的数据是不能丢掉的,在应用关闭之前,需要将数据持久化到硬盘中,
在重启后应可以立即重新恢复 Session 中的数据。这就称为 Session 的钝化与活化。
那么 Session 中的哪些数据能够钝化呢?只有存放在 JVM 堆内存中的实现了 Serializable
类的对象能够被钝化。也就是说,对于字符串常量、基本数据类型常量等存放在 JVM 方法
区中常量池中的常量,是无法被钝化的。
对于监听 Session 中对象数据的钝化与活化,需要注意以下几点:
- 实体类除了要实现 HttpSessionActivationListener 接口外,还需要实现 Serializable 接口。
- 钝化指的是 Session 中对象数据的钝化,并非是 Session 的钝化。所以 Session 中有几个可以钝化的对象,就会发生几次钝化。
- HttpSessionActivationListener 监听器是不需要在 web.xml 中注册的。
1.创建Person类实现HttpSessionActivationListener和Serializable接口:
package Attribute; import java.io.Serializable; import javax.servlet.http.HttpSessionActivationListener; import javax.servlet.http.HttpSessionEvent; public class Person implements HttpSessionActivationListener,Serializable{
private static final long serialVersionUID = -3274136342116934283L; //一定要随机UID 不然看你无法钝化 为什么? 就要看你IO学的怎么样了
private String name; private int 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 void sessionDidActivate(HttpSessionEvent se) { System.out.println("活化" + se.getSession().getId()); } @Override public void sessionWillPassivate(HttpSessionEvent se) { System.out.println("钝化" + se.getSession().getId()); } }
2.在项目中的META-INF目录下创建一个content.xml的文件,在里面写上下面内容:
<?xml version="1.0" encoding="UTF-8"?> <!-- 在项目中的META-INF目录下创建一个content.xml的文件,在里面写上下面内容: 一定要是 content 这个文件名 不然没用 --> <Context> <!-- ClassName 是 序列化相关的东西 maxIdleSwap 是多少秒后去序列化 --> <Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1"> <!-- ClassName 是 序列化相关的东西 directory 存储的位置 --> <Store className="org.apache.catalina.session.FileStore" directory="bihu"/> </Manager> </Context>
一定别写错啊 这玩意
3.3.在jsp中编写下面内容 把 Person 实例化后 将他 存到Session 中:
<%@page import="Attribute.Person"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <% Person p = new Person(); session.setAttribute("Person", p); //当服务器启动时 自动活化 Person 当服务器关闭时 就钝化Person %> </body> </html>
通过上面的设置,可以将session钝化和活化。
启动tomcat访问jsp文件,之后正常关闭tomcat后可以看见控制台输出”钝化”。再次启动tomcat,可以看到控制台输出”活化”。
你会发现 钝化 和 活化的 ID 是一样的 那就没错了 你可以去工作目录去找你钝化后的文件 ser 结尾的 ,但活化后会消失。
自己试一试 主要还是一点 多实践起来