8.3 SessionListeners
一共有四个HttpSession
相关的监听器接口:HttpSessionListener
,HttpSessionActivationListener
、HttpSessionAttributeListener
和HttpSessionBindingListener
。这四个接口都在javax.servlet.http
包中,下面分别对它们进行介绍。
8.3.1HttpSessionListener
当一个HttpSession
创建或者销毁时,容器都会通知所有的HttpSessionListener
监听器,HttpSessionListener
接口有两个方法:sessionCreated
和sessionDestroyed
:
1 2
| void sessionCreated(HttpSessionEvent event) void sessionDestroyed(HttpSessionEvent event)
|
这两个方法都可以接收到一个继承于java.util.Event
的HttpSessionEvent
对象。可以通过调用形参列表中的HttpSessionEvent
对象的getSession
方法来获取当前的HttpSession
。getSession
方法如下:
1
| HttpSession getSession()
|
实例
app08a
应用中的SessionListener
类。这个监听器来统计HttpSession
的数量。它使用了一个AtomicInteger
对象来统计,并且将这个对象保存成ServletContext
范围的属性。每当有一个HttpSession
被创建时,这个AtomicInteger
对象就会加一。每当有一个HttpSession
被销毁时,这个AtomicInteger
对象就会减一。所以这个对象会保存着当前存活的HttpSession
数量。这里使用了AtomicInteger
来代替Integer
类型是为了保证能同步进行加减的操作。
SessionListener类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| package app08a.listener; import java.util.concurrent.atomic.AtomicInteger; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; @WebListener public class SessionListener implements HttpSessionListener, ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { ServletContext servletContext = sce.getServletContext(); servletContext.setAttribute("userCounter", new AtomicInteger()); } @Override public void contextDestroyed(ServletContextEvent sce) {} @Override public void sessionCreated(HttpSessionEvent se) { HttpSession session = se.getSession(); ServletContext servletContext = session.getServletContext(); AtomicInteger userCounter = (AtomicInteger) servletContext .getAttribute("userCounter"); int userCount = userCounter.incrementAndGet(); System.out.println("userCount incremented to :" + userCount); } @Override public void sessionDestroyed(HttpSessionEvent se) { HttpSession session = se.getSession(); ServletContext servletContext = session.getServletContext(); AtomicInteger userCounter = (AtomicInteger) servletContext .getAttribute("userCounter"); int userCount = userCounter.decrementAndGet(); System.out.println("----------" + " userCount decremented to:" + userCount); } }
|
SessionListener
类实现了ServletContextListener
和HttpSessionListener
接口。所以需要实现这两个接口的所有方法。
contextInitialized方法说明
contextInitialized
方法创建了一个AtomicInteger
对象并将其保存在ServletContext
的userCounter
属性中。由于是在应用启动的时候创建,因此这个AtomicInteger
对象的初始值为0
。
1 2 3 4 5 6 7 8 9
| @Override public void contextInitialized(ServletContextEvent sce) { ServletContext servletContext = sce.getServletContext(); servletContext.setAttribute("userCounter", new AtomicInteger()); }
|
sessionCreated方法说明
sessionCreated
方法在每个HttpSession
创建时被调用。当有HttpSession
创建时,从ServletContext
中获取userCounter
属性。然后调用userCounter
的incrementAndGet
方法让计数加一。最后在控制台将userCounter
的值打印出来,可以直观地看到效果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| @Override public void sessionCreated(HttpSessionEvent se) { HttpSession session = se.getSession(); ServletContext servletContext = session.getServletContext(); AtomicInteger userCounter = (AtomicInteger) servletContext .getAttribute("userCounter"); int userCount = userCounter.incrementAndGet(); System.out.println("userCount incremented to :" + userCount); }
|
sessionDestroyed方法说明
sessionDestroyed
方法会在HttpSession
销毁之前被调用。这个方法的实现和sessionCreated
类似,只不过对userCounter
改为减一操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Override public void sessionDestroyed(HttpSessionEvent se) { HttpSession session = se.getSession(); ServletContext servletContext = session.getServletContext(); AtomicInteger userCounter = (AtomicInteger) servletContext .getAttribute("userCounter"); int userCount = userCounter.decrementAndGet(); System.out.println("----------" + " userCount decremented to:" + userCount); }
|
运行效果
可以通过不同的浏览器访问countries.jsp
页面来查看监听器的效果,下面是countries.jsp
的访问URL
:
http://localhost:8080/app08a/countries.jsp
第一次访问时,Java IDE
控制台会打印如下信息:
1
| userCount incremented to :1
|
用同一个浏览器再次访问这个URL
并不会改变userCounter
,因为这属于同一个HttpSession
。使用不同的浏览器访问才能增加userCounter
的值。这时候控制台打印内容如下:
1 2
| userCount incremented to :1 userCount incremented to :2
|
如果你有时间等待HttpSession
过期的话,在控制台也能看到HttpSession
销毁时打印的信息,如下所示:
1 2
| ---------- userCount decremented to:1 ---------- userCount decremented to:0
|