监听器
监听对象
监听ServletContext
、HttpSession
和ServletRequest
等域对象的创建和销毁,以及他们属性修改发生的变化事件,监听器可以在事件发生前后进行一些必要的处理操作。web监听器是Servlet规范定义的一种特殊类。
监听器的应用场景
-
统计在线人数和在线用户
每一个用户第一次访问服务器上的web应用时都会产生一个Session会话,通过统计Session对象的创建就可以统计在线人数。
-
应用启动时完成信息的初始化工作
ServletContext
对象是在服务器启动的时候创建并初始化,在服务器关闭或者web应用移除的时候销毁,所以可以监听servletContext
的创建,在它的初始化函数中完成信息的初始化工作,销毁方法中完成清理工作。 -
网站访问量的统计
每一次的访问,都是伴随着请求,所以可以通过请求来统计网站访问量。
-
与Spring结合
-
Web系统防止用户重复登陆
监听器的启动顺序
同一种类型的监听器,监听器启动(调用初始化函数)的顺序跟在web.xml
下注册监听器的顺序一致,而监听器关闭的顺序是注册顺序的逆序
Java监听器的分类
-
按监听对象分
ServletContext
对象监听器HttpSession
对象监听器ServletRequest
对象监听器
-
按监听事件分
- 域对象自身的创建和销毁事件监听器
- 域对象中属性的创建、替换和消除事件监听器
- 绑定到Session中的某个对象的状态事件监听器
ServletContextListener
- 监听
ServletContext
对象的创建和销毁,ServletContext
对象是在服务器启动的时候创建并初始化,在服务器关闭或者web应用移除的时候销毁
//ServletContext对象创建初始化的时候调用(服务器启动的时候就调用)
public void contextInitialized(ServletContextEvent sce)
//ServletContext对象销毁时调用(服务器关闭或者web应用移除时调用)
public void contextDestroyed(ServletContextEvent sce)
编写Java类实现监听器接口,并实现其接口方法
public class MyServletContextListener implements ServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent sce) {
//进行清理工作
}
@Override
public void contextInitialized(ServletContextEvent sce) {
//ServletContextEvent类中封装着ServletContext对象,用getServletContext()方法取出来后进行特定操作
//在ServletContext对象创建的时候(服务器启动的时候)进行全局属性的设置,在整个web应用生命周期中都可以直接使用
String appName=sce.getServletContext().getInitParameter("appName");
String version=sce.getServletContext().getInitParameter("version");
sce.getServletContext().setAttribute("appName", appName);
sce.getServletContext().setAttribute("version",version);
}
}
web.xml配置(注册监听器、设置初始化参数)
<!--监听器的注册,让我们的web服务器知道有这么个web监听组件,到时候服务器就可以对我们编写的监听器类进行实例化和初始化 -->
<listener>
<listener-class>com.lxc.firstlistener.MyServletContextListener</listener-class>
</listener>
<!--配置多个初始化参数,在web应用启动的时候就进行数据的装载(添加到整个web应用生命周期中),好处是以后如需修改这些
参数,直接修改web.xml中的初始化参数后重启服务器就行,无须重新修改、编译类 -->
<context-param>
<param-name>appName</param-name>
<param-value>ServletContextListener</param-value>
</context-param>
<context-param>
<param-name>version</param-name>
<param-value>1.0</param-value>
</context-param>
HttpSessionListener
监听HttpSession
对象的创建和销毁,HttpSession
对象在用户会话开始(一般是指用户通过浏览器第一次与web应用交互时)的时候创建,HttpSession
是在会话超时、关闭服务器或者手动调用session的invalidate方法session.invalidate()时销毁。(不同会话有不同的Session,web应用运行时会多次调用监听器的sessionCreate()
和sessionDestory()
)
//HttpSession对象创建时调用
public void sessionCreated(HttpSessionEvent hse)
//HttpSession对象销毁时调用
public void sessionDestroyed(HttpSessionEvent hse)
监听器类
public class MyHttpSessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent hse) {
//HttpSessionEvent封装了Session对象,可用getSession()方法取出
//获取SessionId
String sessionId=hse.getSession().getId();
//获取Session创建时间
Date createDate=new Date(hse.getSession().getCreationTime());
System.out.println("sessionId:"+sessionId+" createDate:"+createDate);
}
@Override
public void sessionDestroyed(HttpSessionEvent hse) {
//在session销毁的时候做一些清理工作
String sessionId=hse.getSession().getId();
System.out.println("sessionId:"+sessionId);
}
}
web.xml中的配置
<listener>
<listener-class>com.lxc.firstlistener.MyHttpSessionListener</listener-class>
</listener>
<!-- 因为默认的超时时间为30分钟,为了更好演示程序,我们设置为1分钟(是以分钟为单位) -->
<session-config>
<session-timeout>1</session-timeout>
</session-config>
ServletRequestListener
监听ServletRequest
对象的创建和销毁,ServletRequest
对象在浏览器向服务器发送请求时创建,在请求完成时销毁。(只要是请求就会被这个监听器监听)
//ServletRequest对象创建的时候调用
public void requestInitialized(ServletRequestEvent sre)
//ServletRequest对象销毁时调用
public void requestDestroyed(ServletRequestEvent sre)
监听器类
public class MyServletRequestListener implements ServletRequestListener {
@Override
public void requestInitialized(ServletRequestEvent sre) {
System.out.println("request destory..");
}
@Override
public void requestDestroyed(ServletRequestEvent sre) {
//ServletRequestEvent中封装了ServletRequest对象,取出来后需要强制转换为HttpServletRequest进行处理
HttpServletRequest hsre=(HttpServletRequest)sre.getServletRequest();
String url=hsre.getRequestURI();
System.out.println("request init.URL:"+url);
}
}
web.xml
<listener>
<listener-class>com.lxc.firstlistener.MyServletRequestListener</listener-class>
</listener>
域对象属性的监听
三种域对象的属性监听器都有这三个方法
ServletContextAttributeListener
public class ContextListener implements ServletContextAttributeListener {
@Override
public void attributeAdded(ServletContextAttributeEvent scae) {
ServletContext context=scae.getServletContext();
/*添加属性时调用,获得添加的属性名和值*/
System.out.println("新增的属性:"+scae.getName()+":"+scae.getValue());
}
@Override
public void attributeRemoved(ServletContextAttributeEvent scae) {
/*属性移除时调用,获得移除的属性名和值*/
System.out.println("移除的属性:"+scae.getName()+":"+scae.getValue());
}
@Override
public void attributeReplaced(ServletContextAttributeEvent scae) {
/*属性替换时调用(修改值),获得修改前的属性名和值*/
System.out.println("替换的属性:"+scae.getName()+":"+scae.getValue());
}
web.xml
<listener>
<listener-class>com.lxc.firstlistener.ContextListener</listener-class>
</listener>
HttpSessionAttributeListener
public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {
@Override
public void attributeAdded(HttpSessionBindingEvent hsbe) {
//监听到session添加属性,可以使用hsbe.getSession()获得这个Session
HttpSession session=hsbe.getSession();
}
@Override
public void attributeRemoved(HttpSessionBindingEvent hsbe) {
}
@Override
public void attributeReplaced(HttpSessionBindingEvent hsbe) {
}
}
ServletRequestAttributeListener
public class MyServletRequestAttributeListener implements ServletRequestAttributeListener {
@Override
public void attributeAdded(ServletRequestAttributeEvent sqae) {
HttpServletRequest hrequest=(HttpServletRequest)sqae.getServletRequest();
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent sqae) {
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent sqae) {
}
}