Servlet 事件监听器是一个实现了特定接口的 Java 程序,这个程序专门用于监听 Web 应用中 ServletContext、HttpSession 和 ServletRequest 等对象的创建和销毁过程、监听这些域对象属性的修改以及感知绑定到 HttpSession 域中的某个对象的状态。
Servlet 规范中定义了八种监听器,这八种监听器的类型及作用.
类 型描 述ServletContextListener用于监听 ServletContext 对象的创建与销毁过程HttpSessionListener用于监听 HttpSession 对象的创建和销毁过程ServletRequestListener用于监听 ServletRequest 对象的创建和销毁过程ServletContextAttributeListener用于监听 ServletContext 对象中的属性变更HttpSessionAttributeListener用于监听 HttpSession 对象中的属性变更ServletRequestAttributeListener用于监听 ServletRequest 对象中的属性变更HttpSessionBindingListener用于监听 JavaBean 对象绑定到 HttpSession 对象和从 HttpSession 对象解绑的事件HttpSessionActivationListener用于监听 HttpSession 中对象活化和钝化的过程HttpSessionActivationListener 的描述中涉及活化和钝化的概念, HttpSession 对象从内存中转移至硬盘的过程称为钝化. HttpSession 对象从持久化状态变为运行状态的过程称为活化。
根据监听事件的不同,可以将表中的监听器分为如下三类
(1) 用于监听域对象创建和销毁的事件监听器(ServletContextListener 接口、HttpSessionListener 接口、ServletRequestListener 接口)。
(2) 用于监听域对象属性增加和删除的事件监听器(ServletContextAttributeListener 接口、HttpSessionAttributeListener 接口、ServletRequestAttributeListener 接口)。
(3)用于监听绑定到 HttpSession 域中某个对象状态的事件监听器(HttpSessionBindingListener 接口、HttpSessionActivationListener 接口) 在 Servlet 规范中,这三类事件监听器都定义了相应的接口,在编写事件监听器程序时只需实现对应的接口即可。在使用监听程序时,Web 服务器会根据监听器所实现的接口,把它注册到被监听的对象上,当触发了某个对象的监听事件时,Web 容器将会调用 Servlet 监听器与之相关的方法对事件进行处理。
在许多网站或者软件应用中都有统计当前在线人数这一功能。在通常情况下,当一个用户进入网站时就会创建一个 HttpSession 对象,而当用户离开网站时,HttpSession 对象就会被销毁。在 Servlet 的八种监听器中,HttpSessionListener 监听器就可以监听 Web 应用中 HttpSession 对象的创建和销毁过程。因此,可以使用实现了 HttpSessionListener 接口的监听器统计网站的当前在线人数。
1. 创建监听器[新建一个java类实现HttpSessionListener接口,重写方法]
package com.wangxing.listener; import javax.servlet.ServletContext; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; /** * HttpSessionListener接口用来监听HttpSession对象的创建和销毁 * @author Administrator * */ public class OnlineListener implements HttpSessionListener{ private int count = 0; // 用于统计在线人数变量 //监听HttpSession对象的创建 @Override public void sessionCreated(HttpSessionEvent hse) { count++; // Session对象创建时count变量加1 ServletContext context = hse.getSession().getServletContext(); context.setAttribute("count", new Integer(count)); } //监听HttpSession对象的销毁 @Override public void sessionDestroyed(HttpSessionEvent hse) { count--; // Session对象创建时count变量减1 ServletContext context = hse.getSession().getServletContext(); context.setAttribute("count", new Integer(count)); } }在 OnlineListener.java 中,首先定义了一个用于统计在线人数的成员变量 count。当每次监听到 HttpSession 对象创建时,count 成员变量会加 1。当每次监听到 HttpSession 对象销毁时,count 成员变量会减 1在每次修改 count 成员变量后,还应该将 count 成员变量的值保存到 ServletContext 对象中,以便其他Servlet程序可以从 ServletContext 对象中取出 count 成员变量,从而在页面上显示当前在线用户数量。
2. 在 web.xml 文件中,配置 OnlineListener 事件监听器
<listener> <listener-class>com.wangxing.listener.OnlineListener</listener-class> </listener>3. 创建首页和注销页面
package com.wangxing.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class HomeServlet extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter out=resp.getWriter(); out.println("<html>"); out.println("<head><meta charset=\"utf-8\"><title>HomeServlet</title></head>"); out.println("<body><center>"); Object countobj=req.getSession().getServletContext().getAttribute("count"); int count=(int)countobj; out.println("<h1>当前在线人数:"+count+"</h1>"); out.println("<h2><a href=\"logout\">安全退出</a></h2>"); out.println("</center></body>"); out.println("</html>"); out.close(); } } package com.wangxing.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class LogOutServlet extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //销毁session对象 req.getSession().invalidate(); PrintWriter out=resp.getWriter(); out.println("<html>"); out.println("<head><meta charset=\"utf-8\"><title>LogOutServlet</title></head>"); out.println("<body><center>"); out.println("<h1>你已经退出本系统!</h1>"); out.println("</center></body>"); out.println("</html>"); out.close(); } } <filter> <filter-name>encodingfilter</filter-name> <filter-class>com.wangxing.filter.EncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingfilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <listener> <listener-class>com.wangxing.listener.OnlineListener</listener-class> </listener> <servlet> <servlet-name>home</servlet-name> <servlet-class>com.wangxing.servlet.HomeServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>home</servlet-name> <url-pattern>/home</url-pattern> </servlet-mapping> <servlet> <servlet-name>logout</servlet-name> <servlet-class>com.wangxing.servlet.LogOutServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>logout</servlet-name> <url-pattern>/logout</url-pattern> </servlet-mapping>测试 http://localhost:8080/TestListener/home