一、监听器简介
监听器是web容器对某一些对象的监听,当某些对象发生创建、修改、删除的动作时,
web容器会自动调用对应的监听器中的方法。
例如A是监听器,B是被监听对象,A的监听任务是B回家时来开门。
那么当B一回家,监听器A就会执行开门的操作。
二、监听器用法
2.1.1 ServletContextListener
用于监听ServletContext对象的创建及销毁,实际上就是监听Web应用的生命周期。
首先我们要创建一个类,实现ServletContextListener接口,实现里面的两个方法:
public void contextInitialized(ServletContextEvent sce)//web程序初始化时执行
public void contextDestroyed(ServletContextEvent sce)//web程序销毁时执行
ContextListener:
import java.io.PrintStream; import javax.servlet.ServletContextEvent; public class ServletContextListener implements javax.servlet.ServletContextListener{ PrintStream out = System.out; @Override public void contextInitialized(ServletContextEvent sce) { // TODO Auto-generated method stub out.println("ContextInit"); } @Override public void contextDestroyed(ServletContextEvent sce) { // TODO Auto-generated method stub out.println("ContextDestroyed"); } }
web.xml
<listener> <listener-class>com.listener.ServletContextListener</listener-class> </listener>
当打开Tomcat时,监听器监听到ServletContext开始初始化,会执行contextInitialized(),
打印出ContextInit。当关闭Tomcat时,监听器监听到ServeltContext已关闭,会执行contextDestroyed(),
打印出ContextDestroyed.
2.1.2ServletContextAttrubute
监听ServletContext属性列表发送更改。
比如属性的添加(setAttrubute("a","a")、
修改(setAttribute("a","A"))、删除(removeAttribute("a"))。
ServletContextAttribute中有三个方法:
attributeAdded(ServletContextAttributeEvent scae);//监听添加属性
attributeRemoved(ServletContextAttributeEvent scae)//监听删除属性
attributeReplaced(ServletContextAttributeEvent scae)//监听修改属性
import java.io.PrintStream; import javax.servlet.ServletContextAttributeEvent; import javax.servlet.ServletContextAttributeListener; import javax.servlet.ServletContextEvent; public class ServletContextListener implements ServletContextAttributeListener{ PrintStream out = System.out; @Override public void attributeAdded(ServletContextAttributeEvent scae) { // TODO Auto-generated method stub out.println("AddAttribute"); } @Override public void attributeRemoved(ServletContextAttributeEvent scae) { // TODO Auto-generated method stub out.println("RemovedAttribute"); } @Override public void attributeReplaced(ServletContextAttributeEvent scae) { // TODO Auto-generated method stub out.println("ReplacedAddAttribute"); } }
LoginServlet:
import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.util.HttpPageUtil; public class LoginServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); String username = request.getParameter("username"); ServletContext sc = this.getServletContext(); //添加 sc.setAttribute("Attribute", "addAttribute"); //修改 sc.setAttribute("Attribute", "reAttribute"); //删除 sc.removeAttribute("Attribute"); HttpPageUtil.printHtmlPage(out, true); out.println("SerlvetContextAttribute"); HttpPageUtil.printHtmlPage(out, false); System.out.println("Servlet"); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }
控制台输出:
当LoginServlet中向ServletContext添加属性时,对应监听器监听到添加动作,
执行方法attributeAdded()方法输出AddAttribute,修改属性时执行attributeReplaced()方法
输出ReplacedAddAttribute,删除属性时执行attributeRemoved()方法,输出RemoveAttribute。
2.2.1HttpSessionListener
HttpSessionnLister主要用于监听Session的创建及销毁。
public void sessionCreated(HttpSessionEvent se)//session创建时执行。
public void sessionDestroyed(HttpSessionEvent se)//session销毁时执行。
import java.io.PrintStream; import javax.servlet.http.HttpSessionEvent; public class HttpSessionListener implements javax.servlet.http.HttpSessionListener{ PrintStream out = System.out; @Override public void sessionCreated(HttpSessionEvent se) { // TODO Auto-generated method stub out.println("SeesionCreater"); } @Override public void sessionDestroyed(HttpSessionEvent se) { // TODO Auto-generated method stub out.println("SeesionDestroy"); } }
控制台输出:
但Session创建销毁时,监听器会监听到对应的动作并执行对方法。
2.2.2HttpSessionAttributeListener
主要监听Session对象属性的添加、修改、删除操作。
public void attributeAdded(HttpSessionBindingEvent se);//添加session中属性时执行
public void attributeRemoved(HttpSessionBindingEvent se);//删除session中属性时执行
public void attributeReplaced(HttpSessionBindingEvent se);//修改session中属性时执行
HttpSessionAttributeListener
public class HttpSessionListener implements javax.servlet.http.HttpSessionAttributeListener{ PrintStream out = System.out; @Override public void attributeAdded(HttpSessionBindingEvent se) { // TODO Auto-generated method stub out.println("SessionAttributeAdd"); } @Override public void attributeRemoved(HttpSessionBindingEvent se) { // TODO Auto-generated method stub out.println("SessionAttributeRemove"); } @Override public void attributeReplaced(HttpSessionBindingEvent se) { // TODO Auto-generated method stub out.println("SessionAttributeReplace"); } }
LoginServlet
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; import javax.servlet.http.HttpSession; import com.util.HttpPageUtil;; // http://localhost:8080/TestServlet/Filter/Login public class LoginServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); String username = request.getParameter("username"); HttpSession session = request.getSession(); //添加 session.setAttribute("attribute", "add"); //修改 session.setAttribute("attribute", "replace"); //删除 session.removeAttribute("attribute"); HttpPageUtil.printHtmlPage(out, true); out.println("SessionAttributeListener"); HttpPageUtil.printHtmlPage(out, false); System.out.println("Servlet"); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }
控制台输出:
监听器会添加session中属性的增加、修改、删除,并执行对应方法
输出对应方法中的语句。
2.3.1ServletRequestListener
ServletRequestListener主要监听request的初始化和销毁。
public void requestDestroyed(ServletRequestEvent sre);//request初始化时执行。
public void requestInitialized(ServletRequestEvent sre);//request销毁时执行。
import java.io.PrintStream; import javax.servlet.ServletRequestEvent; public class ServletRequest implements javax.servlet.ServletRequestListener{ PrintStream out = System.out; @Override public void requestDestroyed(ServletRequestEvent sre) { // TODO Auto-generated method stub out.println("RequestDestroy"); } @Override public void requestInitialized(ServletRequestEvent sre) { // TODO Auto-generated method stub out.println("RequestInit"); } }
LoginServlet:
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; import javax.servlet.http.HttpSession; import com.util.HttpPageUtil;; // http://localhost:8080/TestServlet/Filter/Login public class LoginServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("intoServlet"); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }
但在地址栏通过URL访问LoginServlet时:
控制台输出结果:
当发送一个访问请求时,请求初始化被监听器监听到,执行对应方法输出“RequestInit”。
然后到达LoginServlet进行输出"intoServlet",最后请求结束被监听器监听到,执行requestDestroyed方法
输出“RequestDestroy”。
2.3.2 ServletRequestAttributeListener
ServletResqeustAttributerListener主要监听reques中属性的创建、修改、删除。
public void attributeAdded(HttpSessionBindingEvent se);//添加session中属性时执行
public void attributeRemoved(HttpSessionBindingEvent se);//删除session中属性时执行
public void attributeReplaced(HttpSessionBindingEvent se);//修改session中属性时执行
RequestAttributeListener:
import java.io.PrintStream; import javax.servlet.ServletRequestAttributeEvent; public class ServletRequest implements javax.servlet.ServletRequestAttributeListener{ PrintStream out = System.out; @Override public void attributeAdded(ServletRequestAttributeEvent srae) { // TODO Auto-generated method stub out.println("AddAttribute"); } @Override public void attributeRemoved(ServletRequestAttributeEvent srae) { // TODO Auto-generated method stub out.println("RemoveAttribute"); } @Override public void attributeReplaced(ServletRequestAttributeEvent srae) { // TODO Auto-generated method stub out.println("ReplaceAttribute"); } }
LoginServlet:
import java.io.IOException; import java.io.PrintWriter; import java.util.Enumeration; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import com.util.HttpPageUtil;; public class LoginServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //添加 request.setAttribute("attribute", "add"); //修改 request.setAttribute("attribute", "replace"); //删除 request.removeAttribute("attribute"); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }
通过URL调用LoginServlet,
控制台输出:
当在reques中设置属性时,对应监听器会监听到,并调用attributeAdded()方法,输出"AddAttribute".
当修改reqest中属性时,会调用attributeReplaced()方法,输出“ReplaceAttribute”.
当删除reques中属性时会嗲用attributeRemoved()方法,输出“RemoveAttribute”。
三、监听器实例(在线人数统计)
首先在线人数应该是全站可见的,所以人数应该存放在作用域最大的ServletContexte中。
每登入一个用户我们就创建一个Session,Session监听器中人数+1。当一个session销毁时
监听器中人数-1.
OnLineListener:
import java.util.Set; import java.util.TreeSet; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.http.HttpSessionEvent; public class OnLineListener implements javax.servlet.ServletContextListener, javax.servlet.http.HttpSessionListener{ private ServletContext sc = null; private int count = 0;//记录登陆人数 @Override public void sessionCreated(HttpSessionEvent se) { // TODO Auto-generated method stub //当创建用户session时,count++ count++; //将人数设置在ServletContext中 sc.setAttribute("count", new Integer(this.count)); } @Override public void sessionDestroyed(HttpSessionEvent se) { // TODO Auto-generated method stub //当ession销毁时,count-- count--; //将人数设置在ServletContext中 sc.setAttribute("count", new Integer(this.count)); } @Override public void contextInitialized(ServletContextEvent sce) { // TODO Auto-generated method stub //Tomcat启动时获取ServletContext,并设置一个登陆人数(初值为0); this.sc = sce.getServletContext(); this.sc.setAttribute("count", new Integer(this.count)); } @Override public void contextDestroyed(ServletContextEvent sce) { // TODO Auto-generated method stub sc = null; } }
LoginServlet:
import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import com.util.*; // http://localhost:8080/TestServlet/Filter/Login public class LoginServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); String username = request.getParameter("username"); HttpSession session = request.getSession(); //获取ServletContext ServletContext sc = this.getServletContext(); HttpPageUtil.printHtmlPage(out, true); //从ServletContext中获取人数。 out.println("欢迎" + username + "当前在线人数" + ((Integer)sc.getAttribute("count")).intValue()); HttpPageUtil.printHtmlPage(out, false); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Login</title> </head> <body> <!--在.../Page/下重定向 不加 /的相对路径 --> <!-- http://localhost:8080/TestServlet/Page/Filter/Login --> <form name = f1 action ="/TestServlet/Filter/Login" method = "post"> username:<input type = "text" name = "username" value = "${un}"></input><br> password:<input type = "password" name = "password" value = "${pw}"></input><br> <!-- 记住密码 :<input type = "radio" name = "SavePassword" value = "1"><br> --> <input type = "submit" value = "登录"> </form> </body> </html>
每登录一个用户都会为其创建一个Session,这里测试时最好用不同的浏览器。
如果是一个浏览器,此例中多次登录会被认为是一个session,不会触发Session创建监听。