Listener基于Servlet API,用于监听web应用中某些对象、信息的创建、销毁、增加,修改,删除等动作的发生,然后作出相应的响应处理。当范围对象的状态发生变化的时候,服务器自动调用监听器对象中的方法。常用于统计在线人数和在线用户,系统加载时进行信息初始化,统计网站的访问量等等。
分类:
ServletContext对象监听器(ServletContextListener、ServletContextAttributeListener)
HttpSession对象监听器(HttpSessionListener、HttpSessionAttributeListener)
ServletRequest对象监听器(ServletRequestListener、ServletRequestAttributeListener)
一.ServletContextListener监听器的使用
当Servlet容器启动或终止Web应用时,会触发ServletContextEvent事件,该事件由ServletContextListener 来处理。在ServletContextListener接口中定义了处理ServletContextEvent事件的两个方法。
/**
* 启动Web应用时(即启动sevlet容器)调用该方法。在调用完该方法之后,容器再对Filter 初始化,
* 并对那些在Web应用启动时就需要被初始化的Servlet进行初始化。
* ServletContextEvent中包含ServletContext对象
*/
public void contextInitialized(ServletContextEvent sce);
/**
* Web应用终止时(即Servlet 容器终止时)调用该方法,在调用该方法之前,容器会先销毁所有的Servlet和Filter过滤器。
*/
public void contextDestroyed(ServletContextEvent sce);
例子:在服务启动时,将数据库中的数据加载进内存,并将其赋值给一个属性名,其它的 Servlet 就可以通过 getAttribute 进行属性值的访问
1、ServletContext 对象是一个为整个web应用提供共享的内存,任何请求都可以访问里面的内容
2、如何实现在服务启动的时候就动态的加入到里面的内容:我们需要做的有:
1 )实现 servletContextListerner 接口 并将要共享的通过 setAttribute( name,data )方法提交到内存中去;
2 )应用项目通过 getAttribute(name) 将数据取到 。
public class ServletContextLTest implements ServletContextListener{
// 实现其中的销毁函数
public void contextDestroyed(ServletContextEvent sce) {
ServletContext servletContext = servletContextEvent.getServletContext();
// 在整个web应用销毁之前调用,将所有应用空间所设置的内容清空
servletContext.removeAttribute("dataSource");
System.out.println("销毁工作完成...");
}
// 实现其中的初始化函数,当有事件发生时即触发
public void contextInitialized(ServletContextEvent sce) {
ServletContext sct=sce.getServletContext();
// 设置一些基本的内容;比如一些参数或者是一些固定的对象
// 创建DataSource对象,连接池技术 dbcp
BasicDataSource basicDataSource = new BasicDataSource();
basicDataSource.setDriverClassName("com.jdbc.Driver");
basicDataSource.setUrl("jdbc:mysqlocalhost:3306/");
basicDataSource.setUsername("root");
basicDataSource.setPassword("root");
basicDataSource.setMaxActive(10);//最大连接数
basicDataSource.setMaxIdle(5);//最大管理数
//bds.setMaxWait(maxWait); 最大等待时间
// 把 DataSource 放入ServletContext空间中,
// 供整个web应用的使用(获取数据库连接)
servletContext.setAttribute("dataSource", basicDataSource);
System.out.println("应用监听器初始化工作完成...");
System.out.println("已经创建DataSource...");
}
}
在完成上述编码后,仍需在 web.xml 中进行如下配置(或者使用@WebListener),以使得该监听器可以起作用。
<listener>
<listener-class>ServletContextTest.ServletContextLTest</listener-class>
</listener>
二.HttpSessionListener监听器的使用
HttpSessionListener监听器(实现接口) 用来监听HttpSession域 对象的创建和销毁
/**
*
*session创建时调用该方法
*HttpSessionEvent中包含HttpSession
*
*/
public void sessionCreated(HttpSessionEvent se);
/**
*
*session销毁时调用该方法
*HttpSessionEvent中包含HttpSession
*
*/
public void sessionDestroyed(HttpSessionEvent se);
例子:监听器统计在线人数,一个人在线可以同时拥有多个session,导致统计有一定的不准确性
package com.ctrip.framework.riskmanagement.service;
import java.util.HashSet;
import javax.servlet.ServletContext;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
@WebListener
public class SessionListener implements HttpSessionListener {
public void sessionCreated(HttpSessionEvent arg0) {
ServletContext context = arg0.getSession().getServletContext();
if (context.getAttribute("count") == null) {
context.setAttribute("count", 0);
} else {
int count = (Integer) context.getAttribute("count");
context.setAttribute("count", count + 1);
}
}
@SuppressWarnings("unchecked")
public void sessionDestroyed(HttpSessionEvent arg0) {
ServletContext context = arg0.getSession().getServletContext();
if (context.getAttribute("count") == null) {
context.setAttribute("count", 0);
} else {
int count = (Integer) context.getAttribute("count");
if (count < 1) {
count = 1;
}
context.setAttribute("count", count - 1);
}
HttpSession session = arg0.getSession();
String name = (String) session.getAttribute("name");
HashSet<String> nameSet = (HashSet<String>) context.getAttribute("nameSet");
nameSet.remove(name);
}
}
三.ServletRequestListener监听器的使用
ServletRequestListener监听器的使用(实现接口),用来监听HttpRequest域 对象的创建和销毁
/**
* of scope of the web application.
*
* @param sre the ServletRequestEvent containing the ServletRequest
* ServletRequestEvent中包含ServletRequest对象
*/
public void requestDestroyed(ServletRequestEvent sre);
/**
* Receives notification that a ServletRequest is about to come
* into scope of the web application.
*
* @param sre the ServletRequestEvent containing the ServletRequest
* ServletRequestEvent中包含ServletRequest对象
*/
public void requestInitialized(ServletRequestEvent sre);
例子:
import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
/**
* @author kp.li
*
*/
@WebListener
public class RequestListener implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println("request请求要结束了 ,开始留言");
}
@Override
public void requestInitialized(ServletRequestEvent sre) {
System.out.println("request请求创建后,开始监听");
ServletRequest servletRequest = sre.getServletRequest();
System.out.println(servletRequest.getParameter("phoneNum"));
servletRequest.setAttribute("phoneNum", "186782432");
}
}
四. ServletContextAttributeListener、HttpSessionAttributeListener、ServletRequestAttributeListener
该三个listener均是监听相应对象属性新增、修改、删除