Listener监听器
1.是什么? 有什么用?
监听器就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法将立即被执行。
2.为什么要使用监听器
监听器可以用来检测网站的在线人数,统计网站的访问量等等!
3.监听器的内部机制
监听器涉及三个组件:事件源,事件对象,事件监听器
当事件源发生某个动作的时候,它会调用事件监听器的方法,并在调用事件监听器方法的时候把事件对象传递进去。
我们在监听器中就可以通过事件对象获取得到事件源,从而对事件源进行操作!
4.自定义监听器
监听器接口:
监听器定义为接口,监听的方法需要事件对象传递进来,从而在监听器上通过事件对象获取得到事件源,对事件源进行修改!
MyListener:
/**
* 监听器,其实就是一个接口
* 监听事件源的eate和sleep方法
*/
public interface MyListener {
void doEate(Event event);
void doSleep(Event event);
}
事件源:
事件源是一个Person类,它有eat和sleep()方法。
事件源需要注册监听器(即在事件源上关联监听器对象)
如果触发了eat或sleep()方法的时候,会调用监听器的方法,并将事件对象传递进去
/**
* 事件源
*/
public class Person {
//在事件源上定义一个监听器对象
private MyListener listener;
//定义两个方法
public void eate() {
//当调用eate方法时会触发监听器的doEate方法
listener.doEate(new Event(this));
}
public void sleep() {
//当调用sleep方法时会触发监听器的doSleep方法
listener.doSleep(new Event(this));
}
//注册监听器的对象的方法
public void register(MyListener listener) {
this.listener=listener;
}
}
事件对象:
事件对象封装了事件源。
监听器可以从事件对象上获取得到事件源的对象(信息)
/**
* 事件对象Even
*
* 事件对象封装了事件源
*
* 在监听器上能够通过事件对象获取得到事件源
*
*/
public class Event {
private Person eventSource;
public Event() {
super();
}
public Event(Person eventSource) {
super();
this.eventSource = eventSource;
}
public Person getEventSource() {
return eventSource;
}
}
测试类:
/**
* 测试
*/
public class TestDemo {
public static void main(String[] args) {
Person eventSource=new Person();
//注册监听器
eventSource.register(new MyListener() {
@Override
public void doSleep(Event event) {
// TODO Auto-generated method stub
System.out.println(event.getEventSource()+"睡觉了。。。");
}
@Override
public void doEate(Event event) {
// TODO Auto-generated method stub
System.out.println(event.getEventSource()+"吃饭了。。。");
}
});
eventSource.eate();
}
}
Servlet监听器
在Servlet规范中定义了多种类型的监听器,它们用于监听的事件源分别 ServletContext, HttpSession和ServletRequest这三个域对象
和其它事件监听器略有不同的是,servlet监听器的注册不是直接注册在事件源上,而是由WEB容器负责注册,开发人员只需在web.xml文件中使用<listener>
标签配置好监听器,
总共有8个 划分成三种类型
使用方式:
1. 定义一个类,实现接口
2. 注册 | 配置监听器【在WEB-INF里面的web-xml内】
<listener>
<listener-class>it.cast.contextlistener.demo.ContextListenerDemo</listener-class>
</listener>
第一类: 监听对象的创建和销毁
HttpSessionListener、ServletContextListener、ServletRequestListener分别监控着Session、Context、Request对象的创建和销毁
作用:
HttpSessionListener
可以用来收集在线者信息
ServletContextListener
可以获取web.xml里面的参数配置
ServletRequestListener
利用它来,在servletcontext创建的时候,
1. 完成自己想要的初始化工作
2. 执行自定义任务调度。 执行某一个任务。 Timer
1. ServletContextListener
servletcontext创建:
1. 启动服务器的时候
servletContext销毁:
2. 关闭服务器. 从服务器移除项目
/**
* ServletContextListener的示例
*/
public class ContextListenerDemo implements ServletContextListener {
//创建的时候使用
public void contextInitialized(ServletContextEvent sce) {
System.out.println("context创建了。。。");
}
//销毁的时候使用
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("context销毁了。。。");
}
}
2. ServletRequestListener
request创建:
访问服务器上的任意资源都会有请求出现。
访问 html: 会
访问 jsp: 会
访问 servlet : 会
request销毁:
服务器已经对这次请求作出了响应。
/**
* ServletRequestListener的示例
*/
public class RequestListenerDemo implements ServletRequestListener {
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println("Request创建了。。。");
}
public void requestInitialized(ServletRequestEvent sre) {
System.out.println("Request销毁了。。。");
}
}
3. HttpSessionListener
session的创建
只要调用getSession
html: 不会
jsp: 会 getSession();
servlet: 会
session的销毁
超时 30分钟
非正常关闭 销毁
正常关闭服务器(序列化)
/**
*HttpSessionListener的示例
*/
public class SessionListenerDemo implements HttpSessionListener {
public void sessionCreated(HttpSessionEvent se) {
// TODO Auto-generated method stub
System.out.println("session创建了。。。");
}
public void sessionDestroyed(HttpSessionEvent se) {
// TODO Auto-generated method stub
System.out.println("session销毁了。。。");
}
}
第二类:监听三个作用域属性状态变更
ServletContextAttributeListener、HttpSessionAttributeListener、ServletRequestAttributeListener分别监听着ServletContext、Session、Request对象属性的变化
这三个接口中都定义了三个方法来处理被监听对象中的属性的增加,删除和替换的事件,同一个事件在这三个接口中对应的方法名称完全相同,只是接受的参数类型不同。
- attributeAdded()
- attributeRemoved()
- attributeReplaced()
演示HttpSessionAttributeListener:
public class MyHttpSessionDemo implements HttpSessionAttributeListener {
public void attributeAdded(HttpSessionBindingEvent event) {
// TODO Auto-generated method stub
System.out.println("属性被添加了。。。");
}
public void attributeRemoved(HttpSessionBindingEvent event) {
// TODO Auto-generated method stub
System.out.println("属性被删除了。。。");
}
public void attributeReplaced(HttpSessionBindingEvent event) {
// TODO Auto-generated method stub
System.out.println("属性被替换了。。。");
}
}
测试页面:
<%@ 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>
<%
//第二类监听器的示例
session.setAttribute("name", "aa");
session.removeAttribute("name");
session.setAttribute("name", "bb");
%>
</body>
</html>
第三类:监听httpSession里面存值的状态变更
这一类监听器不用注册
- 实现HttpSessionBindingListener接口,JavaBean 对象可以感知自己被绑定到 Session 中和从 Session 中删除的事件【和HttpSessionAttributeListener的作用是差不多的】
- 实现HttpSessionActivationListener接口,JavaBean 对象可以感知自己被活化和钝化的事件(当服务器关闭时,会将Session的内容保存在硬盘上【钝化】,当服务器开启时,会将Session的内容在硬盘式重新加载【活化】) 。。
HttpSessionBindingListener:监听对象与session 绑定和解除绑定 的动作
让javaBean 实现该接口即可:
/**
* 第三类监听器HttpSessionBindingListener的示例
* 监听对象与session 绑定和解除绑定 的动作
*/
public class PersonBean implements HttpSessionBindingListener {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void valueBound(HttpSessionBindingEvent event) {
// TODO Auto-generated method stub
System.out.println("对象被绑定了");
}
public void valueUnbound(HttpSessionBindingEvent event) {
// TODO Auto-generated method stub
System.out.println("对象被解除绑定了");
}
}
HttpSessionActivationListener:用于监听现在session的值 是 钝化 (序列化)还是活化 (反序列化)的动作
session的钝化活化的用意何在:
session中的值可能会很多, 并且我们有很长一段时间不使用这个内存中的值, 那么可以考虑把session的值可以存储到硬盘上【钝化】,等下一次在使用的时候,在从硬盘上提取出来。 【活化】
- 钝化 (序列化):把内存中的数据 存储到硬盘上
- 活化 (反序列化):把硬盘中的数据读取到内存中。
如何让session的在一定时间内钝化?
做配置即可:
1. 在tomcat里面 conf/context.xml 里面配置
对所有的运行在这个服务器的项目生效
2. 在conf/Catalina/localhost/context.xml 配置
对 localhost生效。 localhost:8080
3. 在自己的web工程项目中的 META-INF/context.xml
只对当前的工程生效。
maxIdleSwap : 1分钟不用就钝化
directory : 钝化后的那个文件存放的目录位置。
<Context>
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
<Store className="org.apache.catalina.session.FileStore" directory="itheima"/>
</Manager>
</Context>
钝化之后的文件夹:
F:\webserver\tomcat\apache-tomcat-7.0.52\work\Catalina\localhost\ListenerDemo02\itheima