2011-10-24 102 views
0

我必須在會話超時後註銷用戶。我正在使用EventListenter來清除會話,並且還使用PhaseListener在執行任何處理之前驗證用戶。JSF 2.0會話超時拋出IllegalStateException

我得到以下情況例外,當我嘗試點擊會話之後的任何按鈕已超時:

java.lang.IllegalStateException 
org.apache.catalina.connector.ResponseFacade.reset(ResponseFacade.java:310) 
com.sun.faces.context.ExternalContextImpl.responseReset(ExternalContextImpl.java:821) 
com.sun.faces.context.ExceptionHandlerImpl.throwIt(ExceptionHandlerImpl.java:251) 
com.sun.faces.context.ExceptionHandlerImpl.handle(ExceptionHandlerImpl.java:141) 
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:119) 
com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:113) 
com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) 
javax.faces.webapp.FacesServlet.service(FacesServlet.java:395) 

我的web.xml中有如下條目:

<error-page> 
    <exception-type>javax.faces.application.ViewExpiredException</exception-type> 
    <location>/content/country/default/jsp/login.faces</location> 
</error-page> 
<error-page> 
    <exception-type>java.lang.Throwable</exception-type> 
    <location>/content/country/default/jsp/error.faces</location> 
</error-page> 

從工作的一段代碼該PhaseListener在爲

try{ 
    log.info("------------Check the method call-----------"); 
    if (log.isDebugEnabled()) 
     log.info("Authentication is needed. Navigating to login page."); 
    nh.handleNavigation(fc, null, NavigationConstants.LOGIN_FAILURE.toString()); 
    return; 
}catch(ViewExpiredException ve){ 
    log.info("Got the view expired exception. . . "); 
    FacesContext.getCurrentInstance().getExternalContext().redirect("login.faces"); 
}catch(IllegalStateException e){ 
    log.info("Got the IllegalStateException . . "); 
    FacesContext.getCurrentInstance().getExternalContext().redirect("login.faces"); 
}catch(Exception ex){ 
    log.info("Got the Exception . . ",ex); 
    FacesContext.getCurrentInstance().getExternalContext().redirect("login.faces"); 

回答

0
java.lang.IllegalStateException 
org.apache.catalina.connector.ResponseFacade.reset(ResponseFacade.java:310) 

你得到了這個例外because響應已經被提交。

com.sun.faces.context.ExternalContextImpl.responseReset(ExternalContextImpl.java:821) 
com.sun.faces.context.ExceptionHandlerImpl.throwIt(ExceptionHandlerImpl.java:251) 
com.sun.faces.context.ExceptionHandlerImpl.handle(ExceptionHandlerImpl.java:141) 
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:119) 
com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:113) 

因此,JSF在恢復視圖階段遇到一個例外,需要把它(這樣在錯誤頁面結束了),但是它無法做到,因爲響應已被提交那時(沒有JSF被告知它應該立即提交響應)。

目前尚不清楚這個階段偵聽器的工作時間,但您的主要興趣在於確定在還原視圖階段確切拋出了哪個異常,以及爲什麼響應已在此時被提交。根據目前發佈的代碼和信息無法回答。運行調試器應該告訴你更多關於異常的信息,並跟蹤你提交的代碼流,響應應該告訴你更多關於意外提交的信息。

無論如何,你下面功能需求令我着迷:

我必須退出會話超時後的用戶。我正在使用EventListenter清除會話

我不明白爲什麼這是必要的。登錄用戶通常表示爲會話屬性。如果會話超時,則已登錄的用戶應該自動消失已經。你不需要自己採取任何清理行動。您只需在會話中檢查登錄用戶的存在,無論何時需要根據此用戶執行任何操作。

+0

基本上,應用程序創建一個授權令牌並將其記錄到數據庫中。要求是在會話到期或用戶註銷後應該使其失效。所以我想在sessionDestroy方法中使auth令牌無效。讓我運行調試器,如果我對它有一定的瞭解,我會回覆你。謝謝 – Smita

+0

'HttpSessionListener'實現的'sessionDestroyed()'方法,你的意思是?我仍然想知道那個事件監聽器和相位監聽器與它有什麼關係。該階段偵聽器到底在哪裏運行? – BalusC

+0

是的phaseListener在afterPhase(PhaseEvent事件)方法中,我們檢查用戶身份驗證。我不確定這段代碼是否拋出異常。同樣的代碼也適用於我們直接調用/abc.faces的某些頁面,但對於基本上不適用於某些調用bean特定方法的點擊。 – Smita