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
|
原文链接: 8.3 SessionListeners 8.3.1HttpSessionListener