使用HttpSessionListener接口监听Session的创建和失效、在线统计人数

JavaWeb中的Session 

在JavaWeb中使用HttpSession(以下简称session)对象来表示一个会话。 
正在装载数据…… 
Session的创建(代表会话周期的开始):第一次调用request.getSession()方法时,会创建一个session对象。 
Session的销毁(代表会话周期的结束):在某个请求周期内调用了Session.invalidate()方法,此请求周期结束后,session被销毁;或者是session超时后自动销毁。

 

对于JSP,如果指定了<%@ page session="false"%>,则在JSP中无法直接访问内置的session变量,同时也不会主动创建session,因为此时JSP未自动执行request.getSession()操作获取session。 
在session对象刚创建的第一个请求周期内,调用session.isNew()方法将得到true。 
可以在web.xml文件中配置session默认的超时时间(分钟): 
<session-config> 
    <session-timeout>10</session-timeout> 
</session-config>也可以调用session. setMaxInactiveInterval()方法设置session超时时间(分钟) 
SessionListener 

通过SessionListenr可以监听session的创建和销毁,步骤: 
1.写一个类MySessionListener,实现javax.servlet.http.HttpSessionListener接口及其sessionCreated()、sessionDestroyed()方法

这个接口只包含两个方法,分别对应于Session的创建和失效:
# public void sessionCreated(HttpSessionEvent se); 
# public void sessionDestroyed(HttpSessionEvent se);


2.监听器配置

Servlet3.0中的监听器跟之前2.5的差别不大,唯一的区别就是增加了对注解的支持。在3.0以前我们的监听器配置都是需要配置在web.xml文件中的。在3.0中我们有了更多的选择,之前在web.xml文件中配置的方式还是可以的,同时我们还可以使用注解进行配置。对于使用注解的监听器就是在监听器类上使用@WebListener进行标注,这样Web容器就会把它当做一个监听器进行注册和使用了。

方法一:

在web.xml中配置SessionListener: 
 

<listener> 
    <listener-class>MySessionListener类全名</listener-class> 
</listener> 

方法二:

在监听器类上使用@WebListener注解


当session被创建和销毁时,容器会分别调用SessionListener的sessionCreated()方法和sessionDestroyed()方法,这两个方法中传入了一个参数对象HttpSessionEvent,可以通过此对象的getSession()方法获取session对象。

 

应用:在线人数统计

分析:在网站中经常需要进行在线人数的统计。过去的一般做法是结合登录和退出功能,即当用户输入用户名密码进行登录的时候计数器加1,然后当用户点击退出按钮退出系统的时候计数器减1。这种处理方式存在一些缺点,例如:用户正常登录后,可能会忘记点击退出按钮,而直接关闭浏览器,导致计数器减1的操作没有及时执行;网站上还经常有一些内容是不需要登录就可以访问的,在这种情况下也无法使用上面的方法进行在线人数统计。
  我们可以利用Servlet规范中定义的事件监听器(Listener)来解决这个问题,实现更准确的在线人数统计功能。对每一个正在访问的用户,J2EE应用服务器会为其建立一个对应的HttpSession对象。当一个浏览器第一次访问网站的时候,J2EE应用服务器会新建一个HttpSession对象 ,并触发 HttpSession创建事件 ,如果注册了HttpSessionListener事件监听器,则会调用HttpSessionListener事件监听器的sessionCreated方法。相反,当这个浏览器访问结束超时的时候,J2EE应用服务器会销毁相应的HttpSession对象,触发 HttpSession销毁事件,同时调用所注册HttpSessionListener事件监听器的sessionDestroyed方法。

import java.util.HashSet; 
import javax.servlet.ServletContext; 
import javax.servlet.http.HttpSession; 
import javax.servlet.http.HttpSessionEvent; 
import javax.servlet.http.HttpSessionListener; 

public class MySessionListener implements HttpSessionListener { 

       public void sessionCreated(HttpSessionEvent event) { 
              HttpSession session = event.getSession(); 
              ServletContext application = session.getServletContext(); 
              
              // 在application范围由一个HashSet集保存所有的session 
              HashSet sessions = (HashSet) application.getAttribute("sessions"); 
              if (sessions == null) { 
                     sessions = new HashSet(); 
                     application.setAttribute("sessions", sessions); 
              } 
              
              // 新创建的session均添加到HashSet集中 
              sessions.add(session); 
              // 可以在别处从application范围中取出sessions集合 
              // 然后使用sessions.size()获取当前活动的session数,即为“在线人数” 
       } 

       public void sessionDestroyed(HttpSessionEvent event) { 
              HttpSession session = event.getSession(); 
              ServletContext application = session.getServletContext(); 
              HashSet sessions = (HashSet) application.getAttribute("sessions"); 
              
              // 销毁的session均从HashSet集中移除 
              sessions.remove(session); 
       } 
} 

 以下两种情况下就会发生sessionDestoryed(会话销毁)事件:
   1.执行session.invalidate()方法时 。
      既然LogoutServlet.java中执行session.invalidate()时,会触发sessionDestory()从在线用户 列表中清除当前用户,我们就不必在LogoutServlet.java中对在线列表进行操作了,所以LogoutServlet.java的内容现在是 这样。

      public void doGet(HttpServletRequest request,HttpServletResponse response)
          throws ServletException, IOException {
          // 销毁session
          request.getSession().invalidate();
          // 成功
          response.sendRedirect("index.jsp");
      }

   2.超过会话最大时间时
      如果用户长时间没有访问服务器,超过了会话最大超时时间 ,服务器就会自动销毁超时的session。

      会话超时时间设置:

      方法一:
      会话超时时间可以在web.xml中进行设置,为了容易看到超时效果,我们将超时时间设置为最小值。

      <session-config>
          <session-timeout>1</session-timeout>
      </session-config>

      时间单位是一分钟,并且只能是整数,如果是零或负数,那么会话就永远不会超时。

      方法二:  

      在sessionCreated中添加如下代码,改小超时时间:

      //httpSessionEvent.getSession().setMaxInactiveInterval(5);

@WebListener
public class MySessionListener implements HttpSessionListener {
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        //超时时间设置s
        //httpSessionEvent.getSession().setMaxInactiveInterval(5);
        MySessionContext.AddSession(httpSessionEvent.getSession());
    }

    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        HttpSession session = httpSessionEvent.getSession();
        MySessionContext.DelSession(session);
    }
}

这样只要用浏览器访问该站点,然后5s不刷新之后,sessionDestroyed就会被自动调用了。

 

本文参考自:

1.https://5aijava.iteye.com/blog/163694

2.https://uule.iteye.com/blog/824115

3.https://www.cnblogs.com/wq3435/p/5816468.html

4.https://www.cnblogs.com/strinkbug/p/4943417.html

5.https://blog.csdn.net/zhizhuodewo6/article/details/82019409 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值