每次说起监听器,总是有些空的感觉,那么它到底是个什么东西呢?
一.概念
监听器也叫 Listener,是 Servlet的监听器,它可以监听客户端的请求,服务端的操作等。
监听器可以自动激发一些操作,比如监听在线的用户的数量. 当增加一个 HttpSession时,就激发 sessionCreated(HttpSessionEvent se) 方法,这样就可以给在线人数加 1。
二.执行原理
其实监听器的执行类似于触发器,当某些动作(接口中定义好的)执行时就会触发(至于到底是如何触发的就是底层的问题了)相应的Listener,执行相应的操作;当然如果没有执行对应的动作,则监听器就一直监听着,没有操作。
下面我来举个例子(监听在线用户的数量),来展示一下Listener的执行过程,先来看一下它的时序图:
login.jsp
<%@ page language="java" contentType="text/html; charset=GB18030" pageEncoding="GB18030"%> <% String command = request.getParameter("command"); if ("login".equals(command)) { if ("dan".equals(request.getParameter("userId")) && "123".equals(request.getParameter("password"))) { //登陆成功将用户信息放到session中 session.setAttribute("user_name", request.getParameter("userId")); //设置超时,单位:秒 session.setMaxInactiveInterval(6000); //重定向到主控页面 response.sendRedirect(request.getContextPath() + "/index.jsp"); } } %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=GB18030"> <title>登录</title> <SCRIPT language=JavaScript> function init() { loginForm.userId.focus(); } </SCRIPT> </head> <body onload=init()> <FORM name="loginForm"> <input type="hidden" name="command" value="login"> 用户名: <INPUT name="userId" value="dan" type="text" size="20" maxlength="20"> <p>密 码: <INPUT name="password" value="123" type="password" size="21" maxlength="20"> <input type="submit" onclick="submitForm()" value="提交" name="login" id="login"> </FORM> </body> </html>
TestHttpSessionListener.java
package listener; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; public class TestHttpSessionListener implements HttpSessionListener { @Override public void sessionCreated(HttpSessionEvent se) { System.out.println("-------------TestHttpSessionListener.sessionCreated---------------------"); } @Override public void sessionDestroyed(HttpSessionEvent arg0) { } }
TestHttpSessionAttributeListener.java
package listener; import javax.servlet.http.HttpSessionAttributeListener; import javax.servlet.http.HttpSessionBindingEvent; public class TestHttpSessionAttributeListener implements HttpSessionAttributeListener { @Override public void attributeAdded(HttpSessionBindingEvent se) { System.out.println("name==========" + se.getName()); System.out.println("value==========" + se.getValue()); if ("user_name".equals(se.getName())) { Integer count = (Integer)se.getSession().getServletContext().getAttribute("count"); if (count == null) { count = 1; }else { count++; } se.getSession().getServletContext().setAttribute("count", count); } System.out.println("count=" + se.getSession().getServletContext().getAttribute("count")); } @Override public void attributeRemoved(HttpSessionBindingEvent se) { System.out.println("TestHttpSessionAttributeListener===>>>>>attributeRemoved" + se.getSession().getServletContext().getAttribute("count")); } @Override public void attributeReplaced(HttpSessionBindingEvent arg0) { System.out.println("TestHttpSessionAttributeListener===>>>>>attributeReplaced"); } }
代码写完后,还需要在Web.xml中进行一下配置:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:javaee="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> <listener> <listener-class>listener.TestHttpSessionListener</listener-class> </listener> <listener> <listener-class>listener.TestHttpSessionAttributeListener</listener-class> </listener> </web-app>
执行结果:
代码解析:
1.实现接口
本例是实现了两个监听,一个是对Session的监听(可以没有),一个是对SessionAttribute的监听,在这里将两者都写出来,是让大家对这两者进行一下区分(明白Session和SessionAttribute是分开进行监听的)。
既然是分开的,所以要实现不同的接口,至于为什么一定要实现接口,就是因为Web服务器对不同的接口已经进行了不同的封装,所以当你进行不同的操作时才会调用到不同的监听器上。
2.attributeAdded(HttpSessionBindingEvent se)
HttpSessionAttributeListener接口中的每一个方法中都有一个HttpSessionBindingEvent参数,它是一个事件对象,就是因为对于Session的Attribute的操作触发了该事件,所以才能将对session的attribute的操作触发到响应的方法来。
三.常用监听器
前面只是提到了两种监听器,大家知道不同的操作对应不同的监听器,下面我就来为大家介绍一些常用的监听器:
1.ServletContextAttributeListener:监听对 ServletContext 属性的操作,比如 增加,删除,修改属性.
2.ServletContextListener监听 ServletContext.
当创建 ServletContext 时,激 发 contextInitialized(ServletContextEventsce)方法;当销毁 ServletContext 时,激发 contextDestroyed(ServletContextEvent sce)方 法.
3.HttpSessionListener监听 HttpSession 的操作.
当创建一个 Session 时,激发 session Created(HttpSessionEvent se)方法;当销毁一个Session 时,激 发 sessionDestroyed (HttpSessionEvent se)方法.
4.HttpSessionAttributeListener 监听 HttpSession 中的属性的操作.
当在 Session 增加一个属性时,激发 attributeAdded(HttpSessionBindingEvent se)方法;当在 Session 删除 一个属性时,激发 attributeRemoved(HttpSessionBindingEvent se)方法; 当在Session 属性被重新设置时,激发 attributeReplaced(HttpSessionBindingEvent se) 方法.