使用 Java EE 6 干净地处理会话超时

Posted

技术标签:

【中文标题】使用 Java EE 6 干净地处理会话超时【英文标题】:Cleanly handle session timeout with Java EE 6 【发布时间】:2011-07-22 23:11:33 【问题描述】:

我在 GlassFish 3.0.1 中部署了一个相当简单的 Web 应用程序。我正在使用常规的基于 FORM 的身份验证,并使用 JDBC 领域保护应用程序。视图由 JSF 2 使用 Facelets 处理。

我遇到的问题是,当会话过期时,如果用户单击 h:commandButton 或其他任何回发的内容,他们会看到一个可怕的黄色页面,告诉他们存在 XML 解析错误。在日志中,我得到三个堆栈跟踪:

INFO: PWC2787: Session event listener threw exception
org.jboss.weld.context.ContextNotActiveException: WELD-001303 No active contexts for scope type javax.enterprise.context.RequestScoped
at org.jboss.weld.manager.BeanManagerImpl.getContext(BeanManagerImpl.java:679)
at org.jboss.weld.bean.proxy.ClientProxyMethodHandler.getProxiedInstance(ClientProxyMethodHandler.java:138)
at org.jboss.weld.bean.proxy.ClientProxyMethodHandler.invoke(ClientProxyMethodHandler.java:100)
<snip>

WARNING: ApplicationDispatcher[/core] PWC1231: Servlet.service() for servlet Faces Servlet threw exception
javax.faces.application.ViewExpiredException: viewId:/login.xhtml - View /login.xhtml could not be restored.
at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:212)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:110)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
<snip>

WARNING: Unexpected error forwarding or redirecting to login page
javax.servlet.ServletException: viewId:/login.xhtml - View /login.xhtml could not be restored.
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:325)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1523)
at org.apache.catalina.core.ApplicationDispatcher.doInvoke(ApplicationDispatcher.java:822)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:684)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:517)
<snip>

我似乎找不到一种干净简单的方法来处理这个问题。我尝试在 web.xml 中为 ViewExpiredException 设置错误处理程序,但它从未被调用。我猜系统已经被第一个异常放弃了。现在我真的不太在乎在这种情况下我将用户发送到哪里,只要他们没有看到死亡黄页!

注意:非回发链接可以正确查找并重定向到登录页面。

【问题讨论】:

【参考方案1】:

不幸的是,没有标准的方法来解决这个问题,至少我们在做了相当多的研究后没有发现任何东西。

你可以做的是:

(1) 在 faces-config.xml 中注册你自己的 JSF-ExceptionHandler 并让它处理你想要的任何异常,然后重定向到错误/登录页面。并非完全微不足道,但绝对有可能——我们就是这样做的。

(2) 看看(并使用)Seam-Catch,他们使用相同的机制(但以更优雅的 CDI 符合方式),我们没有使用它,因为它还没有准备好两个月前。

【讨论】:

以上是关于使用 Java EE 6 干净地处理会话超时的主要内容,如果未能解决你的问题,请参考以下文章

如何处理 AJAX 请求中的会话超时

ESXi 6.5 总是会话超时

aiohttp 异步http请求-6.ClientTimeout 整个会话超时

如何在 Java Web 应用程序中动态设置会话超时?

在java中删除会话超时的cookie

AWS Elastic Beanstalk 上的 Java 应用程序会话超时