任务 3 使用监听器统计在线用户数量
关键步骤如下。
- 实现 HttpSessionBindingListener 接口
- 在 valueBound() 和 valueUnbound() 方法中实现用户数量的统计
- 在 web.xml 文件中配置监听器
5.3.1 认识监听器组件
1.Servlet 监听器
监听器是 Web 应用程序事件模型的一部分,当Web 应用中的某些状态发生改变时,
会产生相应的事件。监听器可以接收这些事件,并可以在事件发生时进行相关处理。
使用 Servlet 监听器可以实现对时间的监听。在 Servlet ApI 中共定义了 8 个监听器
接口,可以用于监听 ServletContext、HttpSession、和 ServletRequest 对象的生命周期、
以及这些对象的属性引发的事件。这 8 个监听器接口如表 5-7 所示。
2. HttpSessionBindingListener 接口
如果一个对象实现了 HttpSessionBindingListener 接口 ,当这个对象被添加到 session 或者
![](/qrcode.jpg)
从 session 中删除时, Servlet 容器都能够进行识别并发出相应的通知,在对象接收到通知后,
就可以进行一系列的操作。HttpSessionBindingListener 接口提供的方法如表 5-8 所示。
监听器接口 | 说明 |
---|---|
javax.servlet.ServletContextListener | 实现该接口,可以在Servlet 上下文对象初始化或者销毁时得到通知 |
javax.servlet.ServletContextAttributeListener | 实现该接口,可以在Servlet 上下文中的属性列表发生变化时得到通知 |
javax.servlet.http.HttpSessionListener | 实现该接口,可以在 session 创建后或者失效前得到通知 |
javax.servlet.http.HttpSessionActivatonListener | 实现该接口的对象,如果绑定到 session 中,当 session 被钝化或者激活时,Servlet 容器将通知该对象 |
javax.servlet.http.HttpSessionAttributeListener | 实现该接口,可以在session 中的属性列表发生变化时得到通知 |
javax.servlet.http.HttpSessionBindingListener | 实现该接口,可以是一个对象在绑定 session 或者从 session 中删除时得到通知 |
javax.servlet.ServletRequestListener | 实现该接口,可以在请求对象初始化时或者被销毁时得到通知 |
javax.servlet.SevrletRequestAttributeListener | 实现该接口,可以在请求对象中的属性发生变化时得到通知 |
方法 | 说明 |
---|---|
void valueBound(HttpSessionBindingEvent event) | 当对象被添加到 session 时,由容器调用该方法来通知对象 |
void valueBound(HttpSessionBindingEvent event) | 当对象从 session 中删除时,由容器调用该方法来通知对象 |
5.3.2 网站在线用户数量统计
使用监听器来统计在线用户数量的实现步骤如下。
1)创建用户类实现 HttpSessionBindingListener 接口
关键代码:
public class UserListener implements HttpSessionBingListener{
……
}
2) 在 valueBound() 和 valueUnbound() 方法中实现用户数量的统计。
关键代码:
public class UserListener implements HttpSessionBindingListener
public void valueBound(HttpSessionBindingEvent arg0)
Constants.ONLINE_USER_COUNT++;
}
public void valueUnbound(HttpSessionBindingEvent arg0){
Constants.ONLINE_USER_COUNT--;
}
}
3)登录成功后将 UserListener 实列添加到 session 作用域。
HttpSessionBindingListener 无须进行配置或声明,只要将其实列添加到 session 作用
域即可。登录成功后需执行的关键代码如下:
//创建监听器实列
UserListener userListener = new UserListener();
//将监听器实列添加到 session 作用域
request.getSession()setAttribute("userListener",userListener);
将 UserListener 实列绑定到 session 作用域时,容器会调用其 valueBound() 方法;同
理,该用户会话被销毁时,UserListener 实列会与 session 作用域解绑,则容器会调用其
valueUnbound() 方法。
补充知识
ServletContextListener 接口
Servlet 监听器可以实现对应用程序的监控,尤其是希望在某一个时间发生时
能够及时得到通知,以便执行相应操作的时候。对于监听器,Servlet 提供不同类
型的接口,其中 ServletContexListener 接口用于对 Web 应用程序进行监控,随时
对Servlet 上下文的变化做出响应。下一节将讲解 ServletContextListener 接口。
5.3.3 ServletContexListener 与 Web 应用初始化
ServletContextListener 接口的作用是 Servlet 上下文对象初始化或者销毁时发送通知,
如果希望 Web 应用程序启动时执行一系列初始化操作任务,就可以通过实现 Servlet
ContextListener 接口的方式来完成。 ServletContextListener 接口的方法如表 5-9 所示。
方法 | 说明 |
---|---|
void contextInitialized(ServletContextEvent arg) | 为 Web 应用程序初始化开始时,由 Web 容器调用 |
void contextDestroyed(ServletContextEbent arg) | 当 Servlet 上下文将要关闭时, 由Web 容器调用 |
特别需要指出的是, Web 容器通过 ServletContextEvent 对象来通知 ServletContext-
Listener 接口进行监听。通过 ServletContextEvent 对象的方法可以获取 Servlet 上下文。
获取上下文的语法如下。
public ServletContext getServletContext();
另外一点需要注意的是,ServletContextListener 监听器的实列要想从 Servlet 容器中
接收相关的事件通知,首先需要对自身进行声明,比较常见的做法是在Web 应用程序
的 web.xml 中对监听器类进行声明。
<listener>
<listener-class>
ServletContextListener 监听器实列的全类名
</listener-class>
</listener>
示例6
在启动新闻系统服务时,加载 DataSource 对象,获取数据库连接。
实现步骤:
在应用程序启动时,实现加载 DataSource 对象包括以下步骤。
1)编写监听器,实现使用 JNDI 查找数据源
2)将查找到的数据源保存在 ServletContext 上下文中。
3)编写Servlet 读取上下文,并从中查找数据源。
4)在 web.xml 文件中配置监听器及 Servlet.
关键代码如下。
监听器的关键代码:
public class DataSourceListener implements ServletContextListener{
public void contextInitialized(ServletContextEvent evn){
ServletContext sc = evn.getServletContext();
try{
//初始化上下文
Context cxt = new InitialContext();
//获取与逻辑名相关联的数据源对象
DataSource ds = (DataSource)cxt.lookup("java:comp/env/jdbc/news");
//将DataSource 保存到 ServletContext 上下文中
sc.setAttribute("DS",ds);
}catch(NamingException e){
e.printStackTrace();
}
}
}
Servlet 的关键代码:
public class DataSourceServlet exteds HttpServlet{
protected void doGet(HttpServletRequest request,HttpServletResponse response) throws
ServletException,IOException{
doPost(request,response);
}
protected void doPost(HttpServletRequest request,HttpServletResponse response) throws
ServletException,IOException{
//从 ServletContext 上下文中读取 DataSource 对象
DataSource ds = (DataSource)getServletContext().getAttribute("DS");
System.out.print(ds);
}
}
监听器及 Servlet 配置的关键代码:
<listener>
<listener-class>com.kgc.news.entity.DataSourceListener</listener-class>
</listener>
<servlet>
<description></description>
<display-name>DataSourceServlet</display-name>
<servlet-name>DataSourceServlet</servlet-name>
<servlet-class>com.kgc.news.web.servlet.DataSourceServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DataSourceServlet</servlet-name>
<url-pattern>/DataSourceServlet</url-pattern>
</servlet-mapping>
运行效果……
本任务通过监听器统计网站在线人数的效果……
附录:监听器授课用的是stusystem 项目,,studentsystem 数据库,,素材转下面这个网站。