Servlet API 之 Listener
Servlet API中有一个EventListener,他是一个空接口,他是接下来要介绍的所有监听器的父接口。
1 ServletContextListener
对ServletContext进行监听,对于独立式的web开发程序来说,一个Server有一个Container有一个ServletContext。
所以对ServletContext的监听就是对这个应用程序的监听。
/** * Notification that the web application initialization process is starting. * All ServletContextListeners are notified of context initialisation before any filter or servlet in the web application is initialized. */ public void contextInitialized(ServletContextEvent sce); /** * Notification that the servlet context is about to be shut down.
* All servlets have been destroy()ed before any ServletContextListeners are notified of context destruction. */ public void contextDestroyed(ServletContextEvent sce);
- contextInitialized方法的执行预示着web应用程序正在初始化。所有的ServletContextListener都能够意识到servletcontext对象的初始化,并且它在所有的filter和servlet执行之前就被初始化了。
- contextDestroyed方法的执行预示着servletcontext对象要被消除了。在所有的servlet被销毁之后,servletContextListener们才执行这个方法。
典型的实例就是spring的ContextLoaderListener,至于怎么实现的,不知道。。。
2 ServletContextAttributeListener
对ServletContext中的Attribute进行监听,监听的动作包括追加,修改和删除。
这是对全局的attribute进行监听的监听器。
/** * Notification that a new attribute was added to the servlet context. Called after the attribute is added. */ public void attributeAdded(ServletContextAttributeEvent scab); /** * Notification that an existing attribute has been removed from the servlet context. Called after the attribute is removed. */ public void attributeRemoved(ServletContextAttributeEvent scab); /** * Notification that an attribute on the servlet context has been replaced. Called after the attribute is replaced. */ public void attributeReplaced(ServletContextAttributeEvent scab);
当调用如下方法的时候,就会触发attributeAdded方法。
this.getServletContext().addAttribute("name", "Voctrals");
3 HttpSessionListener
首先HttpSession是一个接口,获得接口的一个对象的方式为:
request.getSession()或者request.getSession(boolean)
request.getSession()和request.getSession(true)是一样的,当相关联的session对象不存在的时候会创建一个HttpSession对象,不然就返回当前的HttpSession对象。
request.getSession(false),当存在HttpSession对象的时候,返回它,否则返回null。
HttpSession对象是一个服务器端对象,它的创建不是随意的,也不是伴随着HttpServletRequest出现的。
只有当调用request.getSession()或者request.getSession(true)之后,才会有这么一个对象保存在服务器端,当同一个用户进行访问的时候,服务器端能够判断出是否是这个session内的请求。
注意如果JSP没有显示的使用 <% @page session="false"%> 关闭session,则JSP文件在编译成Servlet时将会自动加上这样一条语句 HttpSession session = HttpServletRequest.getSession(true);这也是JSP中隐含的 session对象的来历。(http://blog.csdn.net/zsf0615020117/article/details/4225395)
设置session的时长:
<session-config> <session-timeout>1</session-timeout> </session-config>
以分钟为单位。
于是,就有了这个监听器,用于监听HttpSession的创建和销毁:
/** * Notification that a session was created. * @param se the notification event */ public void sessionCreated(HttpSessionEvent se); /** * Notification that a session is about to be invalidated. * @param se the notification event */ public void sessionDestroyed(HttpSessionEvent se);
对于HttpSessionListener的应用最常见的就是统计站点的当前有效访问人数。
Integer currentNum = (Integer)se.getSession().getServletContext().getAttribute("CurrentNum");
se.getSession().getServletContext().setAttribute("CurrentNum", currentNum +1);
4 HttpSessionAttributeListener
这个监听器跟ServletContextAttributeListener很像,只不过他监听的是HttpSession中的Attribute而已。
这就需要考虑一下,什么东西需要放到ServletContext中,什么东西放到HttpSession中了。
HttpSession 是一种数据存储的范围,用来存放用户私有的信息,只对当前用户有效,当前用户的信息不会被访问该站点的其他用户看到.
ServletContext也是一种数据的存储范围,在整个Web应用中只有一个,是一个全局的,共享的范围,保存的信息对访问该站点的所有用户都是有效的.
可见HttpSession是针对于一个用户的,而ServletContext是针对于整个web应用的。
/** * Notification that an attribute has been added to a session. Called after the attribute is added. */ public void attributeAdded(HttpSessionBindingEvent se); /** * Notification that an attribute has been removed from a session. Called after the attribute is removed. */ public void attributeRemoved(HttpSessionBindingEvent se); /** * Notification that an attribute has been replaced in a session. Called after the attribute is replaced. */ public void attributeReplaced(HttpSessionBindingEvent se);
应该注意这三个方法的参数,HttpSessionBindingEvent,不是HttpSessionAttributeEvent(都不存在~。~)
购物车就是一个HttpSession很好的例子,当创建了一个购物车,在购物车里面放了东西,直到付完款把购物车扔掉。
5 HttpSessionBindingListener
这个listener比较特殊,它不是被一个所谓的Listener实现的,而是被一个将要被保存在HttpSession中作为一个Attribute的Java Object实现。
当有一个对象实现了这个监听器,那么这个对象需要追加如下方法:
/** * Notifies the object that it is being bound to a session and identifies * the session. * * @param event the event that identifies the session * * @see #valueUnbound */ public void valueBound(HttpSessionBindingEvent event); /** * Notifies the object that it is being unbound from a session and * identifies the session. * * @param event the event that identifies the session * * @see #valueBound */ public void valueUnbound(HttpSessionBindingEvent event);
这个应该这么理解,当有一个实现了httpSessionBindingListener的实体类的对象被追加到HttpSession中了之后,会触发一个valueBound事件;当移除了这么一个对象的时候,会触发valueUnbound事件。
设想这么一个场景:
现在有一个用户给家里招了一个保姆,这个时候不能让保姆出现了就没事儿了吧,应该给人家保姆安排个房间啥的吧,安排这个房间的工作就应该是在valueBound中实现的。
另外这个监听器是唯一一个不需要在web.xml中注册的一个监听器。
6 HttpSessionActivationListener
7 ServletRequestListener
这是绑定到一个HttpServletRequest的监听器,当有一个请求发送到服务器的时候,这个监听器就会起作用。
/** The request is about to go out of scope of the web application. */ public void requestDestroyed ( ServletRequestEvent sre ); /** The request is about to come into scope of the web application. */ public void requestInitialized ( ServletRequestEvent sre );
应该说这里没有什么可以说的了。
如果想要对每一个请求都进行监听的话,就可以设定这么一个监听器。
8 ServletRequestAttributeListener
基本上也没有什么好说的了,跟上面的HttpSessionAttriubuteListener还有ServletContextAttributeListener基本相同。
只不过它所监听的是HttpServletRequest对象中的attribute的追加,更新和删除。
/** Notification that a new attribute was added to the ** servlet request. Called after the attribute is added. */ public void attributeAdded(ServletRequestAttributeEvent srae); /** Notification that an existing attribute has been removed from the ** servlet request. Called after the attribute is removed. */ public void attributeRemoved(ServletRequestAttributeEvent srae); /** Notification that an attribute was replaced on the ** servlet request. Called after the attribute is replaced. */ public void attributeReplaced(ServletRequestAttributeEvent srae);
以上介绍的就是servletAPI中的8中监听器。