【问题标题】:Handle ViewExpiredException before handle() method in ExceptionHandlerWrapper is called在调用 ExceptionHandlerWrapper 中的 handle() 方法之前处理 ViewExpiredException
【发布时间】:2014-02-14 05:25:52
【问题描述】:

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

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

我已经尝试通过

获取当前上下文
FacesContext fc = FacesContext.getCurrentInstance();

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

我希望我把我的问题说得够清楚了。

提前感谢您的帮助!

问候 塞巴斯蒂安

【问题讨论】:

    标签: jsf-2 servlet-filters viewexpiredexception facescontext


    【解决方案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 个视图。但是,在调用 FilterChain#doFilter() 之前,在 servlet 过滤器中无法检测到这一点。您确实需要在 JSF 上下文中。您可以在PhaseListener 中创建后端会话。例如。在apply request values阶段的beforephase,保证只有在有有效视图时才会被调用。

    顺便说一句,过滤器中的FacesContext 不是null,因为会话已超时,而是因为此时尚未调用负责创建它的FacesServlet。你知道,过滤器在 servlet 之前运行。

    【讨论】:

    • 非常感谢您的详细描述。
    猜你喜欢
    • 2012-02-12
    • 2011-11-26
    • 1970-01-01
    • 2011-04-07
    • 1970-01-01
    • 2014-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多