0

我已经通过 google 和 stackoverflow 进行了搜索,但找不到任何与我类似的问题。

在我的项目中,我正在正确处理 ViewExpiredException 并向用户显示当前会话已超时的自定义页面。这很好用,但我想在此消息显示给用户之前做一些事情。实际上,我在这里使用 2 个不同的会话,一个在前端,一个在后端,所以这个想法是在当前会话超时时不启动新的后端会话。当我在 doFilter 方法中时,是否有可能获取 ViewExpiredException,所以我不启动新的后端会话(只是因为不需要它)?或者还有其他方法吗?

我已经尝试通过获取当前上下文

FacesContext fc = FacesContext.getCurrentInstance();

但显然上下文为空,因为会话超时。在 ExceptionHandlerWrapper 中,我可以访问 UnhandledExceptionQueuedEvents,但这对我没有帮助,因为我之前需要这些信息。

我希望我的问题足够清楚。

提前感谢您的帮助!

问候塞巴斯蒂安

4

1 回答 1

1

通常ViewExpiredException在会话超时时触发 POST 请求时抛出。因此,这应该在过滤器中执行:

boolean post = "POST".equals(request.getMethod());
boolean timedout = request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid();

if (post && timedout) {
    // JSF will guaranteed throw ViewExpiredException when state saving is set to server.
}

但这并不能涵盖所有可能的情况。ViewExpiredException会话未超时时也可能发生。例如,当客户端传递了一个无效javax.faces.ViewState参数时,或者当关联的视图已从 LRU 映射中剪除时,默认情况下可以保存 15 个视图。然而,在调用之前,这在 servlet 过滤器中是无法检测到的FilterChain#doFilter()。您确实需要在 JSF 上下文中。您可以在PhaseListener. 例如,在应用请求值阶段的前阶段,保证只有在有有效视图时才会调用。

顺便说一句,因为会话已超时,所以FacesContext不在过滤器中,而是因为负责创建它的人在那个时候还没有被调用。你知道,过滤器在 servlet 之前运行。nullFacesServlet

于 2014-01-24T08:41:22.730 回答