JSF Ajax(ViewRoot)更新后重定向

JSF Ajax(ViewRoot)更新后重定向,ajax,jsf,redirect,omnifaces,Ajax,Jsf,Redirect,Omnifaces,我使用omnifaces FullAjaxExceptionHandler在ajax请求触发任何异常时重定向,在我的例子中是捕获ViewExpiredException 我会尽力解释我的情况: 1) 我有一个index.xhtml页面,其中有一个commandButton(ajax请求),用于使会话无效,并返回一个类似于“/login?faces redirect=true”的操作 2) 在同一浏览器中打开index.xhtml两次 3) 在第一个index.xhtml中,单击按钮(会话无效并重

我使用omnifaces FullAjaxExceptionHandler在ajax请求触发任何异常时重定向,在我的例子中是捕获ViewExpiredException

我会尽力解释我的情况:

1) 我有一个index.xhtml页面,其中有一个commandButton(ajax请求),用于使会话无效,并返回一个类似于“/login?faces redirect=true”的操作

2) 在同一浏览器中打开index.xhtml两次

3) 在第一个index.xhtml中,单击按钮(会话无效并重定向到login.xhtml)

考虑到这一点,我有一个自定义的PhaseListener来检查用户是否成功登录,login.xhtml用于公共访问,但index.xhtml限于授权用户,web.xml用于查看过期,403错误为:

<error-page>
    <exception-type>javax.faces.application.ViewExpiredException</exception-type>
    <location>/index.xhtml</location>
</error-page>
<error-page>
    <error-code>403</error-code>
    <location>/403.xhtml</location>
</error-page>

javax.faces.application.ViewExpiredException
/index.xhtml
403
/403.xhtml
4) 转到第二个index.xhtml(此时会话无效),现在单击按钮启动异常

FullAjaxExceptionHandler捕获ViewExpiredException并尝试呈现index.xhtml,但与此同时,我的phaselistener正在检查用户是否已授权,如会话无效、用户未授权以及我的phaselistener激发响应SenderRor(403),但没有显示403.xhtml,因为这是一个ajax请求

如何从PhaseListener发送403错误以显示403.xhtml?responseSendError正在取消FullAjaxExceptionHandler的正常进程,在该异常发生时,不会发生重定向


此外,为了澄清视图何时过期,我需要重定向到index.xhtml,因为在生产中我使用的是CAS(中央身份验证服务)。

具体问题本质上与
FullAjaxExceptionHandler
无关。如果不使用它,您仍然会遇到完全相同的问题。在ajax请求上无法使用
responseandError()
,至少有两个原因:

  • ajax响应必须具有状态200才能成功处理
  • ajax响应必须表示有效的JSF ajax XML结构,而不是普通的HTML页面
  • PhaseListener
    中,最好的选择是使用

    诚然,这最终是一个HTTP200响应,但这是到目前为止,当您希望在ajax请求中完整显示错误页面时所能得到的最好结果



    与具体问题无关,如果抛出了
    ViewExpiredException
    ,则几乎所有情况下的原因都是会话过期。让异常的错误页面直接指向
    /login.xhtml
    ,而不是
    /index.xhtml
    ,这样做更有意义。或者,至少对一些
    /expired.xhtml
    页面更友好,其中解释了最终用户为什么会出现在那里,他的选项是什么,以及一些链接。

    具体问题本质上与
    FullAjaxExceptionHandler
    无关。如果不使用它,您仍然会遇到完全相同的问题。在ajax请求上无法使用
    responseandError()
    ,至少有两个原因:

  • ajax响应必须具有状态200才能成功处理
  • ajax响应必须表示有效的JSF ajax XML结构,而不是普通的HTML页面
  • PhaseListener
    中,最好的选择是使用

    诚然,这最终是一个HTTP200响应,但这是到目前为止,当您希望在ajax请求中完整显示错误页面时所能得到的最好结果



    与具体问题无关,如果抛出了
    ViewExpiredException
    ,则几乎所有情况下的原因都是会话过期。让异常的错误页面直接指向
    /login.xhtml
    ,而不是
    /index.xhtml
    ,这样做更有意义。或者,至少对一些
    /expired.xhtml
    页面更友好,其中解释了最终用户为什么会出现在那里,他的选项是什么,以及一些链接。

    在这种情况下,我需要阅读web.xml以获得配置的错误页面。我将更改代码。谢谢你,巴卢斯。在这种情况下,我需要阅读web.xml以获得配置的错误页面。我将更改代码。谢谢你,巴卢斯。
    ExternalContext ec = context.getExternalContext();
    
    if (context.getPartialViewContext().isAjaxRequest()) {
        ec.redirect(ec.getRequestContextPath() + "/403.xhtml");
    } else {
        ec.responseSendError(403, "Unauthorized");
    }