2012-08-05 65 views
1

在用戶關閉瀏覽器並走開的情況下,我想在會話超時時記錄日誌。例如,作爲系統引起的註銷而不是用戶請求(我已經有工作和測試的代碼來記錄用戶請求的註銷)。如果瀏覽器關閉,JSF會話過期階段監聽器

由於用戶沒有主動提交請求(特別是如果它只是現在未使用的會話在服務器上超時的問題),我不認爲過濾器是可能的。這可以通過階段監聽器完成嗎?如果是的話,你能提供一些見解或骨架,或至少指出我如何做到這一點的正確方向。

我的理解是,服務器上的會話仍然是活動的,直到它超時或其他一些機制使其無效。因此,我假設階段偵聽器也將能夠告訴您是否作爲登錄方法的一部分,在用戶以全新視圖,其他機器等重新登錄之前終止任何現有會話。

我是確定研究,但至少要開始時指向正確的方向。 :)

在第二個注意:是否有可能區分會話超時和視圖過期?


想我會後我結束了基於該建議的解決方案:

public class ElsSoulardSessionListener implements HttpSessionListener { 

    @EJB 
    private SessionLogger sessionLogger = new SessionLogger(); 
    private SessionLogDTO sessionData = new SessionLogDTO(); 
    private ElsDateTimeFunctions ts = new ElsDateTimeFunctions(); 
    private static final Logger logger = Logger.getLogger(ElsSoulardSessionListener.class.getSimpleName()); 

    @Override 
    public void sessionCreated(HttpSessionEvent se) { 
     // Nothing to do yet 
    } 

    @Override 
    public void sessionDestroyed(HttpSessionEvent se) { 
     logger.log(Level.FINE, "SESSION DESTROYED LISTENER"); 

     HttpSession session = se.getSession(); 
     finalizeUserSessionLog(session); 
    } 

    /** 
    * Utility method to finalize user's session log entry. Returns 
    * early if the session log isn't found or more than one is returned. 
    * @param session 
    */ 
    private void finalizeUserSessionLog(HttpSession session) { 

     String sessionId = session.getId(); 
     LogoutReasonType logoutReason = (LogoutReasonType) session.getAttribute("logoutreason"); 

     if (logoutReason == null) { 
      logoutReason = LogoutReasonType.SESSION_TIMEOUT; 
     } 

     try { 
      sessionData = sessionLogger.findBySessionId(sessionId); 
     } catch (NonexistentEntityException | UnexpectedResultSetSizeException ex) { 
      logger.log(Level.WARNING, " sessionDestroyed ", ex); 
      return; 
     } 

     Calendar now = ts.getUtcDateTimeAsCalendar(); 
     sessionData.setLogoutTimestamp(now); 
     sessionData.setLogoutReason(logoutReason); 
     sessionLogger.update(sessionData); 

    } 
} 
+0

您可以使用[HttpSessionListener](http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpSessionListener.html )來處理會話更改。 – 2012-08-05 17:03:11

回答

2

如果這有助於你...

在我們的應用已經擴展HttpSessionListener並使用sessionDestroyed方法記錄會話超時事件。

,並註冊了相同的web.xml

<listener> 
    <listener-class> 
     com.ourpackage.OurHttpSessionListener 
    </listener-class> 
</listener> 
+0

好吧,我以爲我不能將ejbs注入到聽衆中,但是它確實在調用managedbeans,然後無法正確調用我的ejbs ......真的不問。 :)我只是做了我所需要的東西,它不是直接從聽衆那裏注入,包括注入我的loggingservice ejb,它像一個魅力一樣工作。嘗試新事物的樂趣。謝謝。 – BillR 2012-08-07 02:50:46

0

我相信,你只能通過ServletFilters趕上servlet容器的事件。在servlet請求之後,PhaseListener只存在於JSF「會話」中。檢查JSF生命週期以確保。之後,您可以創建另一個請求以使JSF中的「會話」失效