(十五)监听器
一、JavaWeb中的监听器
1.1 基本概念
JavaWeb中的监听器是Servlet规范中定义的一种特殊类,它用于监听web应用程序中的ServletContext, HttpSession和 ServletRequest等域对象的创建与销毁事件,以及监听这些域对象中的属性发生修改的事件。
1.2 Servlet监听器的分类
在Servlet规范中定义了多种类型的监听器,它们用于监听的事件源分别为ServletContext,HttpSession和ServletRequest这三个域对象
Servlet规范针对这三个对象上的操作,又把多种类型的监听器划分为三种类型:
- 监听域对象自身的创建和销毁的事件监听器。
- 监听域对象中的属性的增加和删除的事件监听器。
- 监听绑定到HttpSession域中的某个对象的状态的事件监听器。
1.3 监听ServletContext域对象的创建和销毁
ServletContextListener接口用于监听ServletContext对象的创建和销毁事件。实现了ServletContextListener接口的类都可以对ServletContext对象的创建和销毁进行监听。
当ServletContext对象被创建时,激发contextInitialized (ServletContextEvent sce)方法。
当ServletContext对象被销毁时,激发contextDestroyed(ServletContextEvent sce)方法。
ServletContext域对象创建和销毁时机:
创建:服务器启动针对每一个Web应用创建ServletContext
销毁:服务器关闭前先关闭代表每一个web应用的ServletContext
1.4 监听HttpSession域对象的创建和销毁
HttpSessionListener 接口用于监听HttpSession对象的创建和销毁
创建一个Session时,激发sessionCreated (HttpSessionEvent se) 方法
销毁一个Session时,激发sessionDestroyed (HttpSessionEvent se) 方法。
1.4.1 利用监听HttpSession域对象实现网站计数器
1.4.1.2 编写主页(IndexServlet.java(urlpatting=index))
package 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; /** * Servlet implementation class IndexServlet */ public class IndexServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * Default constructor. */ public IndexServlet() { // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); request.getSession(); // 这行代码很重要,一般来说用户第一次访问某个网站的时候服务器会自动分配给用户浏览器一个session对象,
//但是并不是百分百分配,尤其是低版本的浏览器,如果用户浏览器没有session,那么本题的监听器就无法工作
PrintWriter out=response.getWriter(); out.print("当前网站在线人数为:"+this.getServletContext().getAttribute("count")); } }
1.4.1.3 编写监听器来监视session的创建和销毁。count.java
package listener; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; public class Count implements HttpSessionListener { public Count() { // TODO Auto-generated constructor stub } public void sessionCreated(HttpSessionEvent arg0) { Long count=0L; Object obj=arg0.getSession().getServletContext().getAttribute("count"); //拿到count值,Object类型 if(obj!=null){ count=Long.parseLong(obj+""); // 把obj转为Long类型 } count++; //不管是不是第一个用户访问,都要加1,注意这里的位置,如果写在if语句结尾,那么第一个访问本网站的人的count=null arg0.getSession().getServletContext().setAttribute("count", count); //如果这个网站被第一个人访问,则count=0并存到ServletContext里;
//否则会执行上面的if()进行增加1操作在存到ServletContext里 } public void sessionDestroyed(HttpSessionEvent arg0) { Long count=0L; Object obj=arg0.getSession().getServletContext().getAttribute("count"); if(obj!=null){ count=Long.parseLong(obj+""); } count--; arg0.getSession().getServletContext().setAttribute("count", count); } }
解析:sessionDestroyed方法只有当session对象被销毁时才会调用,而session对象只有当生命周期到了或者调用销毁方法之后才会被销毁,关闭浏览器只是把用户端的sessionId号清掉,用户再次访问的时候就无法把sessionID加在requset头上请求给服务器,服务器只能重新分配给用户浏览器一个新的session对象,当然这个新的session对象是没有原来存放的信息的。
结果:
1.5 监听ServletRequest域对象的创建和销毁
ServletRequestListener接口用于监听ServletRequest 对象的创建和销毁
Request对象被创建时,监听器的requestInitialized(ServletRequestEvent sre)方法将会被调用
Request对象被销毁时,监听器的requestDestroyed(ServletRequestEvent sre)方法将会被调用
ServletRequest域对象创建和销毁时机:
创建:用户每一次访问都会创建request对象
销毁:当前访问结束,request对象就会销毁
- 要想让监听器工作 ,web.xml必须有
- <listener>
- <listener-class>包名 . 类名</listener-class>
- </listener>