【问题标题】:Differentiate between session destroyed by timeout and session destroyed manually in session timeout listener [duplicate]在会话超时侦听器中区分由超时销毁的会话和手动销毁的会话[重复]
【发布时间】:2013-11-06 08:42:07
【问题描述】:

我想实现一个监听器,如果会话过期就会被调用,我发现我可以创建一个实现接口HttpSessionListener的监听器,并重写方法sessionDestroyed

public class SessionListener implements HttpSessionListener {

   @Override
   public void sessionCreated(HttpSessionEvent sessionEvent) {
      // TODO Auto-generated method stub
   }

   @Override
   public void sessionDestroyed(HttpSessionEvent sessionEvent) {
         // TODO Auto-generated method stub         
   }
}

但是问题是每次销毁session时都会调用这个方法,比如登录和注销,那么我怎么知道session过期后session销毁了,或者除了HttpSessionListener还有其他的解决方法。

PS:我在应用程序中使用 Spring 框架。

【问题讨论】:

  • 注意:sessionDestroyed 在会话被删除时被调用,这有时会晚于超时——看看这个问题和分析器,它不是你问题的答案,但它是你的应该知道stackoverflow.com/questions/5390177/…
  • 我认为您无法通过会话侦听器“开箱即用”区分这两种情况。为什么需要?

标签: java spring session


【解决方案1】:

也许你可以尝试这样猜测:

possible_timeout = (CurrentTime - LastAccessedTime) >= MaxInactiveInterval。

// HttpServlet

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    System.out.println("Inside doGet(HttpServletRequest,HttpServletResponse)");

    HttpSession session = request.getSession(true);
    System.out.println("Session Id : " +session.getId() );
    System.out.println( "Is New Session : " + session.isNew() );

    int timeout = 10;
    session.setMaxInactiveInterval(timeout);

    System.out.println( "Max Inactive Interval : " + session.getMaxInactiveInterval() );

    System.out.println("Exiting doGet(HttpServletRequest,HttpServletResponse)");
    System.out.println();

}


// SessionEventListener

public void sessionCreated(HttpSessionEvent httpSessionEvent) {
    System.out.println("In sessionCreated(HttpSessionEvent) ");
    HttpSession httpSession = httpSessionEvent.getSession();
    System.out.println("Session Id :"+httpSession.getId() );
    System.out.println("Exiting sessionCreated(HttpSessionEvent) ");
    System.out.println();
}


public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {

    System.out.println("In sessionDestroyed(HttpSessionEvent) ");

    HttpSession httpSession = httpSessionEvent.getSession();
    long createdTime = httpSession.getCreationTime();
    long lastAccessedTime = httpSession.getLastAccessedTime();
    int maxInactiveTime = httpSession.getMaxInactiveInterval();
    long currentTime = System.currentTimeMillis();

    System.out.println("Session Id :"+httpSession.getId() );
    System.out.println("Created Time : " + createdTime);
    System.out.println("Last Accessed Time : " + lastAccessedTime);
    System.out.println("Current Time : " + currentTime);
    boolean possibleSessionTimeout = (currentTime-lastAccessedTime) >= (maxInactiveTime*1000);

    System.out.println("Possbile Timeout : " + possibleSessionTimeout);
    System.out.println("Exiting sessionDestroyed(HttpSessionEvent)");
    System.out.println();
}

输出如下:

Inside doGet(HttpServletRequest,HttpServletResponse)
In sessionCreated(HttpSessionEvent) 
Session Id :39F84968757E85ED89E7565639322F1F
Exiting sessionCreated(HttpSessionEvent) 

Session Id : 39F84968757E85ED89E7565639322F1F
Is New Session : true
Max Inactive Interval : 10
Exiting doGet(HttpServletRequest,HttpServletResponse)

In sessionDestroyed(HttpSessionEvent) 
Session Id :39F84968757E85ED89E7565639322F1F
Created Time : 1383729761582
Last Accessed Time : 1383729761587
Current Time : 1383729815839
Possbile Timeout : true
Exiting sessionDestroyed(HttpSessionEvent)

我观察到不一定会立即检测到超时。似乎有一个线程定期检查会话超时。此外,还会对每个请求进行检查。

【讨论】:

  • 当 servlet 中的会话超时时,我已经在 weblogic 服务器中对此进行了测试。但与实际差异相差约 500 毫秒。有什么想法吗?
  • @LahiruRuhunage 简而言之,您的意思是超时发生在配置的间隔之前吗?这没有任何意义。如果您的意思更多,它可能只是意味着容器大约每半秒检查一次会话超时(对于您拥有的给定负载)。
  • 是的,当我在会话超时时检查时差时它很短。我不知道具体是什么原因。可能是我必须得到上限。但我没有尝试,因为我使用了过滤器来跟踪会话超时。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-25
  • 1970-01-01
  • 1970-01-01
  • 2016-11-19
  • 2014-02-09
  • 2012-05-25
相关资源
最近更新 更多