监听器
1什么是监听器
1.监听器(Listener):是一个专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时,立即采取相应的行动。监听器其实就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法立即被执行
简而言之:所谓的监听器就是一个能够监听程序内容或者状态是否发生改变的一个Java类
有点类似现实世界中大厦里的火灾警报器
补充讲解:与监听器相关的术语
事件源:指的是被监听对象(汽车)
监听器:指的是监听的对象(报警器)
事件源和监听器绑定:在汽车上安装报警器
事件:指的是事件源对象的改变(踹了汽车一脚)----主要功能获得事件源对象。
2监听器的作用
导读模块:虽然监听器的作用很强大,但是servlet中并没有相关的实现类,只是有一些接口,而这也恰恰体现出了servlet的灵活性
1.那么servlet中都提供了哪些监听器呢?
补充:1)其实servlet中的监听器主要是针对request,session,servletContext开展的
2)监听器要想起作用则必须要有实现类,而实现类要起作用,则必须要有动作,所谓的动作其实就是事件,所谓的事件就是与之关联的一些类
3)servlet中一共有8个监听器接口,6个事件
1.1 8个监听器接口和6个事件:
1、ServletContextListener接口
[接口方法] contextInitialized()与 contextDestroyed()
[接收事件] ServletContextEvent
[触发场景] 在Container加载Web应用程序时(例如启动 Container之后),会呼叫contextInitialized(),而当容器移除Web应用程序时,会呼叫contextDestroyed ()方法。
2、ServletContextAttributeListener
[接口方法] attributeAdded()、 attributeReplaced()、attributeRemoved()
[接收事件] ServletContextAttributeEvent
[触发场景] 若有对象加入为application(ServletContext)对象的属性,则会呼叫attributeAdded(),同理在置换属性与移除属性时,会分别呼叫attributeReplaced()、attributeRemoved()。
3、ServletRequestListener
[接口方法] requestInitialized()与 requestDestroyed()
[接收事件] RequestEvent
[触发场景] 在request(HttpServletRequest)对象建立或被消灭时,会分别呼叫这两个方法。
4、ServletRequestAttributeListener
[接口方法] attributeAdded()、 attributeReplaced()、attributeRemoved()
[接收事件] HttpSessionBindingEvent
[触发场景] 若有对象加入为request(HttpServletRequest)对象的属性,则会呼叫attributeAdded(),同理在置换属性与移除属性时,会分别呼叫attributeReplaced()、 attributeRemoved()。
5、HttpSessionListener
[接口方法] sessionCreated()与sessionDestroyed ()
[接收事件] HttpSessionEvent
[触发场景] 在session (HttpSession)对象建立或被消灭时,会分别呼叫这两个方法。
6、HttpSessionActivationListener
[接口方法] sessionDidActivate()与 sessionWillPassivate()
[接收事件] HttpSessionEvent
[触发场景] Activate与Passivate是用于置换对象的动作,当session对象为了资源利用或负载平衡等原因而必须暂时储存至硬盘或其它储存器时(透 过对象序列化),所作的动作称之为Passivate,而硬盘或储存器上的session对象重新加载JVM时所采的动作称之为Activate,所以容 易理解的,sessionDidActivate()与 sessionWillPassivate()分别于Activeate后与将Passivate前呼叫。
7、HttpSessionAttributeListener
[接口方法] attributeAdded()、 attributeReplaced()、attributeRemoved()
[接收事件] HttpSessionBindingEvent
[触发场景] 若有对象加入为session(HttpSession)对象的属性,则会呼叫attributeAdded(),同理在置换属性与移除属性时,会分别呼叫attributeReplaced()、 attributeRemoved()。
8、HttpSessionBindingListener
[接口方法] valueBound()与valueUnbound()
[接收事件] HttpSessionBindingEvent
[触发场景] 实现HttpSessionBindingListener接 口的类别,其实例如果被加入至session(HttpSession)对象的属性中,则会呼叫 valueBound(),如果被从session(HttpSession)对象的属性中移除,则会呼叫valueUnbound(),实现 HttpSessionBindingListener接口的类别不需在web.xml中设定。
小结与分类:
备:一共分为三大类
(1)监听ServletContext、Request、Session对象的创建和销毁,需要在web.xml中配置
ServletContextListener
ServletRequestListener
HttpSessionListener
友情提示:这三种是最常用的了…
(2)监听ServletContext、Request、Session对象属性的变化,需要在web.xml中配置
ServletContextAttributeListener
ServletRequestAttributeListener
HttpSessionAttributeListener
(3)监听Session内部的对象,不需要再web.xml中配置
HttpSessionActivationListener
HttpSessionBindingListener
2.监听器的作用:
统计在线人数,利用HttpSessionLisener
加载初始化信息:利ServletContextListener
统计网站访问量
实现访问监控
后续的Spring等框架中也要用到
3监听器的应用举例–实现统计在线人数
导读模块:为了要实现应用举例为此我们讲解案例之实现统计在线人数1.监听器使用步骤:
1)创建实现类实现需要的接口
2)在web.xml中配置节点进行声明
3)实现接口中的方法
示例代码:
1)创建SessionListener 并实现HttpSessionListener接口package
com.rj.bd.manage.listeners;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import com.sun.org.apache.bcel.internal.generic.NEW;
/**
*
*@desc session监听器其目的是为了实现统计在线人数
*@author rjx
*@time 2018年12月14日上午9:18:20
*
**/
public class SessionListener implements HttpSessionListener {
/**
* @desc 1.session创建的时候触发
*/
@Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("Session 开始创建了:: ID="+se.getSession().getId());
ServletContext ctx = se.getSession( ).getServletContext( );
Integer numSessions = (Integer) ctx.getAttribute("numSessions");
if (numSessions == null) {
numSessions = new Integer(1);
}
else {
int count = numSessions.intValue( );
numSessions = new Integer(count + 1);
}
ctx.setAttribute("numSessions", numSessions);
}
/**
* @desc 2.session销毁的时候触发
*/
@Override
public void sessionDestroyed(HttpSessionEvent se)
{
System.out.println("Session 销毁了:: ID="+se.getSession().getId());
ServletContext ctx=se.getSession().getServletContext();
Integer numSessions = (Integer)ctx.getAttribute("numSessions");
if(numSessions == null) {
numSessions = new Integer(0);
}
else {
int count = numSessions.intValue( );
numSessions = new Integer(count - 2);
}
ctx.setAttribute("numSessions", numSessions);
}
}
2)在manager模块的查询展示页面给予阐释:当前在线人数为:<%=application.getAttribute(“numSessions”) %>个人
4扩展:监听器,过滤器,servlet的级别
【Listener】->【Filter】->【Servlet】
5监听器的应用举例之–预加载初始化一些数据信息
package com.rj.bd.manage.listeners;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
*
*@desc 上下文内容监听器其目的
*@author rjx
*@time 2018年12月14日下午3:47:31
*
**/
public class MyLiceneListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("===============servlet服务初始化(也就是tomcat正式启动成功)==================");
System.out.println("***************1.可以开始预加载一些信息了****************");
ServletContext context = sce.getServletContext();
/**
* 1.可以预先加载连库4要素
*/
Map<String, Object> map=new HashMap<String, Object>();
map.put("username", "root");
map.put("password", "root");
map.put("drivername", "com.mysql.jdbc.Driver");
map.put("url", "jdbc://..........");
context.setAttribute("map", map);
/**
* 2.也可以在这里实现注入....其实也就是Spring框架核心的注入的原理所在。。。。。(后续讲)
*/
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("===============servlet服务销毁(也就是tomcat重新部署)==================");
}
}
6监听器的应用举例之–Request请求监听器记录ip
package com.rj.bd.manage.listeners;
import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
/**
*
*@desc Request请求监听器其目的是为了记录请求初始化和销毁••时记录ServletRequest IP地址
*@author rjx
*@time 2018年12月14日下午6:01:22
*
**/
public class MyServletRequestListener implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent sre) {
ServletRequest servletRequest = sre.getServletRequest();
System.out.println("ServletRequest destroyed. Remote IP="+servletRequest.getRemoteAddr());
}
@Override
public void requestInitialized(ServletRequestEvent sre) {
ServletRequest servletRequest = sre.getServletRequest();
System.out.println("ServletRequest initialized. Remote IP="+servletRequest.getRemoteAddr());
}
}
使用场景:可以通过分析获取到的ip地址进而获取到请求的ip分布情况