Java Web之监听器总结

1.监听器的概念

监听器(Listener),是Servlet的监听器,它可以监听客户端的请求、服务端的操作等。通过监听器,可以自动激发一些操作,比如监听在线的用户的数量。

2.监听器的用途

  • 统计在线用户
  • 系统启动时加载初始化信息
  • 统计网站访问量
  • 跟spring结合

3.创建一个监听器的步骤

  1. 创建一个实现监听器接口的类
  2. 配置web.xml或使用注解

监听器分三类共八种,其中有两个特殊的监听器创建步骤不是上面所讲的那样,后面我们会讲。

配置web.xml

<listener>
    <listener-class>监听器的路径</listener-class>
</listener>

使用注解

直接在监听器类的开头使用@WebListener即可。

4.监听器的启动顺序(对于同类监听器)

  • 若在web.xml中配置有多个监听器,则按照配置的顺序一一加载。(如果使用注解则无法定义顺序)
  • 若在web.xml中有过滤器,监听器和Servlet,则优先级监听器 > 过滤器 > Servlet。

5.监听器的分类

按监听的对象划分:

  • 用于监听应用程序环境对象(ServletContext)的事件监听器
  • 用于监听用户会话对象(HttpSession)的事件监听器
  • 用于监听请求消息对象(ServletRequest)的事件监听器

按监听的事件划分:

  • 用于监听域对象自身的创建和销毁的事件监听器
  • 用于监听域对象中属性的增加和删除的事件监听器
  • 用于监听绑定到HttpSession域中的某个对象的状态的事件监听器

这里写图片描述

在创建的时候,会让我们选择是哪一类监听器
这里写图片描述

下面我们按照监听的事件来详细说一说这些监听器。

监听域对象自身的创建和销毁的事件监听器

(1)ServletContetx———————>ServletContextListener

ServletContextListener接口源码如下

package javax.servlet;
import java.util.EventListener;
public interface ServletContextListener extends EventListener {
    // 初始化时调用
    public void contextInitialized ( ServletContextEvent sce );
    // 销毁时调用
    public void contextDestroyed ( ServletContextEvent sce );
}

该监听器在启动tomcat后,就会进行加载。通过contextInitialized 方法的参数,可以获取初始化参数。一个web应用程序中只有一个ServletContext对象,一个ServletContext对象可以对应多个ServletContextListener。

该监听器的主要用途是:定时器、全局属性对象。


(2)HttpSession——————————–>HttpSessionListener

HttpSessionListener接口的源码如下:
package javax.servlet.http;
import java.util.EventListener;
public interface HttpSessionListener extends EventListener {
    // 客户端第一次开启一个网页时调用
    public void sessionCreated ( HttpSessionEvent se );
    // session过期时调用
    public void sessionDestroyed ( HttpSessionEvent se );
}

该监听器在启动tomcat后,用户第一次打开网页,就会产生一个session,可以在web.xml中设置session过期时间,当session过期时,就调用监听器的销毁方法。

一个web应用程序中可以有多个HttpSession对象,一个HttpSession对象可以对应多个HttpSessionListener。

主要用途:统计在线人数、记录访问日志。


(3)ServletRequest——————————–>ServletRequestListener

ServletRequestListener接口的源码如下

package javax.servlet;
import java.util.EventListener;
public interface ServletRequestListener extends EventListener {
    // 请求完成后立即销毁
    public void requestDestroyed ( ServletRequestEvent sre );
    // 用户发送请求时调用该方法
    public void requestInitialized ( ServletRequestEvent sre );
}

该监听器在启动tomcat后,用户只要向服务器发送了请求,就会触发(比如用户请求打开某一个网页),请求完成后销毁(当请求的网页加载完成后)。

主要用途:读取参数、记录访问历史



监听域对象中属性增加和删除的监听器

(1)ServletContext————————>ServletContextAttributeListener

ServletContextAttributeListener接口的源码如下

package javax.servlet;
import java.util.EventListener;
public interface ServletContextAttributeListener extends EventListener {
    public void attributeAdded(ServletContextAttributeEvent scab);
    public void attributeRemoved(ServletContextAttributeEvent scab);
    public void attributeReplaced(ServletContextAttributeEvent scab);
}



(2)HttpSession—————————->HttpSessionAttributeListener

HttpSessionAttributeListener接口的源码如下

package javax.servlet.http;
import java.util.EventListener;
public interface HttpSessionAttributeListener extends EventListener {
    public void attributeAdded ( HttpSessionBindingEvent se );
    public void attributeRemoved ( HttpSessionBindingEvent se );
    public void attributeReplaced ( HttpSessionBindingEvent se );
}



(3)ServletRequest————————>ServletRequestAttributeListener

ServletRequestAttributeListener接口的源码如下

package javax.servlet;
import java.util.EventListener;
public interface ServletRequestAttributeListener extends EventListener {
    public void attributeAdded(ServletRequestAttributeEvent srae);
    public void attributeRemoved(ServletRequestAttributeEvent srae);
    public void attributeReplaced(ServletRequestAttributeEvent srae);
}

上述三个接口里的方法都一样,attributeAdded方法在添加属性时调用,attributeRemoved方法在移除属性时调用,attributeReplaced方法在属性替换时调用。看看下面的代码

// 这里会分别调用它们的attributeAdded方法
 request.setAttribute("requestname", "requestvalue");
 request.getSession().setAttribute("sessionname", "sessionvalue");
 request.getSession().getServletContext().setAttribute("contextname", "contextvalue");
 // 触发ServletRequestAttributeListener的attributeReplaced方法
 request.setAttribute("requestname", "requestvalue");
// 这里会分别调用它们的attributeRemoved方法
 request.removeAttribute("requestname");
 request.getSession().removeAttribute("sessionname");
 request.getSession().getServletContext().removeAttribute("contextname");



监听绑定到HttpSession域中的某个对象的状态的事件监听器(该类监听器不用在web.xml中配置)

(1)HttpSessionBindingListener:绑定(valueBound方法)————->解除绑定(valueUnbound方法)

HttpSessionBindingListener接口的源码如下

package javax.servlet.http;
import java.util.EventListener;
public interface HttpSessionBindingListener extends EventListener {
    // 绑定
    public void valueBound(HttpSessionBindingEvent event);
    // 解除绑定
    public void valueUnbound(HttpSessionBindingEvent event);
}

所谓对session进行数据绑定,就是调用session.setAttribute()把HttpSessionBindingListener保存进session中。

使用SetAttribute(“xxx”, 实现了该接口的类的实例对象)。比如request.getSession().setAttribute(“test”, new Test());就把Test的对象绑定到了HttpSession域中(调用valueBound方法)。

valueUnbound的触发条件是以下三种情况:

  • 执行session.invalidate()时。
  • session超时,自动销毁时。
  • 执行session.setAttribute(“onlineUserListener”,
    “其他对象”);或session.removeAttribute(“onlineUserListener”);将listener从session中删除时。

HttpSessionBindingListener和HttpSessionListener之间的最大区别:HttpSessionListener只需要设置到web.xml中就可以监听整个应用中的所有session。HttpSessionBindingListener必须实例化后放入某一个session中,才可以进行监听。

从监听范围上比较,HttpSessionListener设置一次就可以监听所有session,HttpSessionBindingListener通常都是一对一的。

正是这种区别成就了HttpSessionBindingListener的优势,我们可以让每个listener对应一个username,这样就不需要每次再去session中读取username,进一步可以将所有操作在线列表的代码都移入listener,更容易维护。



(2)HttpSessionActivationListener:钝化(sessionWillPassivate方法)—————–>活化(SessionDidActivate方法)

HttpSessionActivationListener接口的源码如下

package javax.servlet.http;
import java.util.EventListener;
public interface HttpSessionActivationListener extends EventListener { 
    public void sessionWillPassivate(HttpSessionEvent se); 
    public void sessionDidActivate(HttpSessionEvent se);
} 

注意:实现此接口的同时,还需实现Serializable接口。活化(从硬盘到内存,序列化)和钝化(从内存到硬盘,反序列化)。

其实就是在用户访问的时候,假如服务器突然关闭了,这个时候,用户的session就不存在了,假如是购物网站,也就相当于,用户好不容易选好的物品,刚刚添加到购物车,结果,因为服务器的突然关闭一下,什么都没了,这样很不好,于是我们就需要实现会话的持久化。

钝化和活化可以让我们在重新启动服务器之后用户的session还在服务器中存在!即用户session的东西还全部在。因为服务器在关闭的时候把用户的session存储到硬盘了(钝化),保存在tomcat目录下的work->Catalina->localhost->项目名->SESSION.ser,在重新启动服务器之后,我们又从硬盘中恢复到内存中!(注意,只要用户还没关闭浏览器,那个session会一直存在用户的客户端的)。启动后,用户的信息就不会丢失!


好了,监听器的总结就到这里了。

个人博客http://www.codeliu.com

猜你喜欢

转载自blog.csdn.net/a_helloword/article/details/80041171