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
- 监听web对象创建与销毁的监听器
监听器的创建和使用
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 结尾的 ,但活化后会消失。
自己试一试 主要还是一点 多实践起来