1.创建生命周期事件监听器
在建立以“Demo”的web project的基础上,点击菜单“File”->“New”->“Class”打开类创建向导对话框如下图。通过“Add”按钮,搜索ServletContextListener添加ServletContextListener 监听器、搜索ServletRequestListener添加ServletRequestListener 监听器和 搜索HttpSessionListener添加HttpSessionListener 监听器;然后点击“Finish” 按钮完成创建。
2. 编写监听器类代码:
package cn; import java.util.Date; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.ServletRequestEvent; import javax.servlet.ServletRequestListener; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; public class EventListener implements ServletRequestListener, ServletContextListener, HttpSessionListener { @Override public void sessionCreated(HttpSessionEvent arg0) { // 当用一个会话创建,则给当前在线人数加1 int cnt=0; ServletContext context = arg0.getSession().getServletContext(); Object sessionCnt = context.getAttribute("sessionCnt"); if(sessionCnt != null){ cnt = (Integer)sessionCnt; } cnt++; context.setAttribute("sessionCnt",cnt); } @Override public void sessionDestroyed(HttpSessionEvent arg0) { // 当有一个会话关闭时,则给当前在线人数减1 int cnt =0; ServletContext context = arg0.getSession().getServletContext(); Object sessionCnt = context.getAttribute("sessionCnt"); if(sessionCnt != null){ cnt = (Integer)sessionCnt; cnt--; } context.setAttribute("sessionCnt",cnt); } @Override public void contextDestroyed(ServletContextEvent arg0) {} @Override public void contextInitialized(ServletContextEvent arg0) { // 保存应用启动时间 arg0.getServletContext().setAttribute("StartDate",new Date()); } @Override public void requestDestroyed(ServletRequestEvent arg0) {} @Override public void requestInitialized(ServletRequestEvent arg0) { // 每有一个请求,则计数 int cnt = 0; Object reqcnt = arg0.getServletContext().getAttribute("reqcnt"); if(reqcnt != null){ cnt = (Integer)reqcnt; } cnt++; arg0.getServletContext().setAttribute("reqcnt",cnt); } }3.在web.xml注册监听器类的配置代码(添加在<web-app></web-app>中)
<listener> <listener-class>cn.EventListener</listener-class> </listener>4.创建一个jsp页面显示统计结果:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE> <html> <head> <title>生命周期事件</title> </head> <body> <p>当前应用启动时间:<%=application.getAttribute("StartDate") %></p> <p>当前在线人数:<%=application.getAttribute("sessionCnt") %></p> <p>处理请求数:<%=application.getAttribute("reqcnt") %></p> </body> </html>运行结果如下:
(1)当用户第一次访问Web应用中支持Session的某个网页时,就会开始一个新的Session,
(2)当在同一个浏览器中同时打开多个标签,发送同一个请求或不同的请求,仍是同一个session;
(3)当不在同一个窗口中打开相同的浏览器时,发送请求,仍是同一个session;
(4)当使用不同的浏览器时,发送请求,即使发送相同的请求,是不同的session;
(5)当把当前某个浏览器的窗口全关闭,再打开,发起相同的请求时,就是本文所阐述的,是不同的session,但是它和session的生命周期是没有关系的.
(6)Session是存在于服务器端的,当把浏览器关闭时,浏览器并没有向服务器发送任何请求来关闭Session,自然Session也不会被销毁,等到默认的时间后,自动销毁。一般默认时间为20-30分钟。(这就是为什么关闭浏览器后当前在线人数没有立即减少的原因。)
运行机制:
当一个Session开始时,Servlet容器会创建一个HttpSession对象,那么在HttpSession对象中,可以存放用户状态的信息Servlet容器为HttpSession对象分配一个唯一标识符即Sessionid,Servlet容器把Sessionid作为一种Cookie保存在客户端的 浏览器 中用户每次发出Http请求时,Servlet容器会从HttpServletRequest对象中取出Sessionid,然后根据这个Sessionid找到相应的HttpSession对象,从而获取用户的状态信息。
Session结束生命周期方法:
一个是Session.invalidate()方法,不过这个方法在实际的开发中,并不推荐,可能在强制注销用户的时候会使用;一个是当前用户和服务器的交互时间超过默认时间后,Session会失效。