一、概念:
所谓的监听器是指对整个WEB环境的监听,当被监视的对象(ServletContext)发生情况(生命周期,setAttribute)时,立即调用相应的方法进行处理。
二、监听器的分类:
1、按监听的对象划分
( 1).用于监听应用程序环境对象(ServletContext)的事件监听器
(2).用于监听用户会话对象(HttpSession)的事件监听器
(3).用于监听请求消息对象(ServletRequest)的事件监听器.
2、按监听的事件类项划分
(1).用于监听域对象自身的创建和销毁的事件监听器
(2).用于监听域对象中的属性的增加和删除的事件监听器
(3).用于监听绑定到HttpSession域中的某个对象的状态的事件监听器.
三、监听作用域对象的创建和销毁:
域对象创建和销毁的事件监听器就是用来监听 ServletContext, HttpSession, HttpServletRequest 这三个对象的创建和销毁事件的监听器。
1、域对象的创建和销毁时机:
( 1) ServletContext
创建:是在 Web 服务器启动并加载某个 Web 应用程序时创建相应的ServletContext 对象.
销毁:是在 Web 服务器关闭或卸载时为每个 Web 应用程序销毁相应的ServletContext 对象.
ServletContextListener对象:
ServletContextListener接口用于监听 ServletContext 对象的创建和销毁事件,当 ServletContext 对象被创建时,激发
public void contextInitalized(ServletContextEvent sce)方法.
当 ServletContext 对象被销毁时,激发
public void contextDestroyed(ServletContextEvent sce)方法.
里面的参数是ServletContextEvent事件是在servlet对象创建时自动激活的事件.
package test.listener; import java.util.ArrayList; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import test.domain.User; /** * 实现了ServletContextListener就可以对servletContext的创建和销毁监听 */ public class TestServletContextListener implements ServletContextListener { /* * 系统启动的时候创建 当sevletcontext被创建的时候该方法执行 */ @Override public void contextInitialized(ServletContextEvent sce) { System.out.println("servletcontext初始化的时候执行"); System.out.println(sce.getServletContext() == sce.getSource()); /* * 1. 当系统启动的时候你可以给当系统准备一些数据。。。 */ // 在系统启动的时候就准备了一个在线用户列表... sce.getServletContext().setAttribute("ONLINEUSER_IN_SERVLETCONTEXT", new ArrayList<User>()); } /* * 当servletContext被销毁的时候执行 */ @Override public void contextDestroyed(ServletContextEvent sce) { System.out.println("servletcontext销毁的时候执行"); sce.getServletContext().removeAttribute("ONLINEUSER_IN_SERVLETCONTEXT"); } }
(2) HttpSession
创建:是在浏览器开始与服务器会话时创建,
销毁:是在调用HttpSession.invalidate();超过了Sessiond的最大有效时间间隔,服务器进程被停止的时候。
HttpSessionListener 接口用于监听HttpSession对象的创建和销毁.
创建一个Session时,激发
public void sessionCreated(HttpSessionEvent se)方法
销毁一个Session时,激发
public void sessionDestroyed(HttpSessionEvent se)方法。
package test.listener; import java.util.List; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; import test.domain.User; public class TestHttpSessionListener implements HttpSessionListener { /* * 当session创建的时候该监听器的方法执行 */ @Override public void sessionCreated(HttpSessionEvent se) { System.out.println("sessionCreated..."+se.getSession().getId()); } /* * 当session销毁的时候该监听器的方法执行 */ @Override public void sessionDestroyed(HttpSessionEvent se) { System.out.println("sessionDestroyed..."+se.getSession().getId()); //1. 得到session的user对象 User user = (User) se.getSession().getAttribute("USER_IN_SESSION"); //2. 该user对象从在线用户列表中删除... List<User> onlineusers= (List<User>) se.getSession().getServletContext().getAttribute("ONLINEUSER_IN_SERVLETCONTEXT"); onlineusers.remove(user); } }
(3) ServletRequest
创建:每次请求开始时创建.
销毁:每次访问结束后销毁.
ServletRequestListener 接口用于监听ServletRequest 对象的创建和销毁.
创建一个ServletRequest 对象时,激发
public void requestInitialized(ServletRequestEvent sre)方法
销毁一个ServletRequest时,激发
public void requestDestroyed(ServletRequestEvent sre)方法.
package test.listener; import javax.servlet.ServletRequestEvent; import javax.servlet.ServletRequestListener; public class TestServletRequestListener implements ServletRequestListener { /* * * 1. ServletRequestListener的优先于过滤器Filter执行 request对象初始化的时候执行 */ @Override public void requestInitialized(ServletRequestEvent sre) { System.out.println("requestInitialized.........."); } /* * request对象销毁的时候执行 */ @Override public void requestDestroyed(ServletRequestEvent sre) { System.out.println("requestDestroyed.........."); } }
四、域对象中属性的变更的事件监听器
就是用来监听 ServletContext, HttpSession, HttpServletRequest 这三个对象中的属性变更信息事件的监听器。
这三个监听器接口分别是ServletContextAttributeListener, HttpSessionAttributeListener 和ServletRequestAttributeListener,这三个接口中都定义了三个方法来处理被监听对象中的属性的增加,删除和替换的事件,同一个事件在这三个接口中对应的方法名称完全相同,只是接受的参数类型不同.
1、attributeAdded 方法
当向被监听器对象中增加一个属性时,web容器就调用事件监听器的 attributeAdded 方法进行响应,这个方法接受一个事件类型的参数,监听器可以通过这个参数来获得正在增加属性的域对象和被保存到域中的属性对象各个域属性监听器中的完整语法定义为:
public void attributeAdded(ServletContextAttributeEvent scae) public void attributeAdded(HttpSessionAttributeEvent hsbe) public void attributeAdded(ServletRequestAttributeEvent srae)
2、attributeRemoved方法
当删除被监听对象中的一个属性时,web 容器调用事件监听器的这个方法进行响应
各个域属性监听器中的完整语法定义为:
public void attributeRemoved(ServletContextAttributeEvent scae) public void attributeRemoved (HttpSessionBindingEvent hsbe) public void attributeRemoved (ServletRequestAttributeEvent srae)
3、attributeReplaced 方法
当监听器的域对象中的某个属性被替换时,web容器调用事件监听器的这个方法进行相应各个域属性监听器中的完整语法定义为:
package test.listener; import java.util.List; import javax.servlet.http.HttpSessionAttributeListener; import javax.servlet.http.HttpSessionBindingEvent; import test.domain.User; public class TestHttpSessionAttributeListener implements HttpSessionAttributeListener { public void attributeAdded(HttpSessionBindingEvent se) { if (se.getName().equals("USER_IN_SESSION")) { List<User> onlineuser = (List<User>) se.getSession() .getServletContext() .getAttribute("ONLINEUSER_IN_SERVLETCONTEXT"); onlineuser.add((User) se.getValue()); } } public void attributeRemoved(HttpSessionBindingEvent se) { if (se.getName().equals("USER_IN_SESSION")) { List<User> onlineuser = (List<User>) se.getSession() .getServletContext() .getAttribute("ONLINEUSER_IN_SERVLETCONTEXT"); onlineuser.remove((User) se.getValue()); } } public void attributeReplaced(HttpSessionBindingEvent se) { } } package test.listener; import javax.servlet.ServletContextAttributeEvent; import javax.servlet.ServletContextAttributeListener; public class TestServletContextAttributeListener implements ServletContextAttributeListener { @Override public void attributeAdded(ServletContextAttributeEvent scab) { if (scab.getName().equals("zhangsan")) { System.out.println("往sevletContext上添加的名字" + scab.getName() + " 值为===" + scab.getValue()); } } @Override public void attributeRemoved(ServletContextAttributeEvent scab) { if (scab.getName().equals("zhangsan")) { System.out.println("从sevletContext上删除的名字" + scab.getName() + "和删除的值==" + scab.getValue()); } } @Override public void attributeReplaced(ServletContextAttributeEvent scab) { if (scab.getName().equals("zhangsan")) { System.out.println("从sevletContext上修改的名字" + scab.getName() + "和被修改之前的值==" + scab.getValue()); System.out.println("得到被修改过后的值" + scab.getServletContext().getAttribute(scab.getName())); } } } package test.listener; import javax.servlet.ServletRequestAttributeEvent; import javax.servlet.ServletRequestAttributeListener; public class TestServletRequestAttributeListener implements ServletRequestAttributeListener { public TestServletRequestAttributeListener() { System.out.println("构造函数执行了......"); } public void attributeAdded(ServletRequestAttributeEvent srae) { } public void attributeRemoved(ServletRequestAttributeEvent srae) { } public void attributeReplaced(ServletRequestAttributeEvent srae) { } }
五、感知 Session 绑定的事件监听器
保存在 Session 域中的对象可以有多种状态:绑定到 Session 中;从 Session 域中解除绑定;随 Session 对象持久化到一个存储设备中;随 Session 对象从一个存储设备中恢复.
Servlet 规范中定义了两个特殊的监听器接口来帮助 JavaBean 对象了解自己在 Session 域中的这些状态:
HttpSessionBindingListener接口
HttpSessionActivationListener接口 ,
实现这两个接口的类不需要 web.xml 文件中进行注册.
1、HttpSessionBindingListener接口
实现了HttpSessionBindingListener接口的 JavaBean 对象可以感知自己被绑定到 Session 中和从 Session 中删除的事件,当对象被绑定到 HttpSession 对象中时,web 服务器调用该对象的 void valueBound(HttpSessionBindingEvent event) 方法,当对象从 HttpSession 对象中解除绑定时,web 服务器调用该对象的 void valueUnbound(HttpSessionBindingEvent event)方法。
2、HttpSessionActivationListener接口.
package test.domain; import javax.servlet.http.HttpSessionBindingEvent; import javax.servlet.http.HttpSessionBindingListener; public class User implements HttpSessionBindingListener{ private String username; private String password; private String ip; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public void valueBound(HttpSessionBindingEvent event) { /* //当该对象被放到session中的时候执行.... System.out.println("valueBound....."); List<User> onlineuses= (List<User>) event.getSession().getServletContext().getAttribute("ONLINEUSER_IN_SERVLETCONTEXT"); onlineuses.add(this);*/ } @Override public void valueUnbound(HttpSessionBindingEvent event) { /*//当被对象从session中删除的时候执行 System.out.println("valueUnbound....."); List<User> onlineuser = (List<User>) event.getSession().getServletContext().getAttribute("ONLINEUSER_IN_SERVLETCONTEXT"); onlineuser.remove(this);*/ } public String getIp() { return ip; } public void setIp(String ip) { this.ip = ip; } }