JSF 2.0会话超时抛出IllegalStateException

时间:2011-10-24 20:01:42

标签: jsf

我必须在会话超时后注销用户。我正在使用EventListenter来清除会话,并使用PhaseListener来验证用户,然后再进行任何处理。

当我在会话超时后尝试点击任何按钮时,我得到以下异常:

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");

1 个答案:

答案 0 :(得分: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来清除会话

我不明白为什么这是必要的。登录用户通常表示为会话属性。如果会话超时,则登录用户已经会自动消失。您不需要自己采取任何清理操作。只要您需要根据它执行任何操作,您只需在会话中检查已登录用户的状态