【问题标题】:Ajax request after session timeout shows <partial-response> [duplicate]会话超时后的 Ajax 请求显示 <partial-response> [重复]
【发布时间】:2016-06-18 06:22:19
【问题描述】:

Omnifaces 2.0、Primefaces 5、wildFly 8.2

如果我尝试在浏览器中使用注册的FullAjaxExceptonHandler 进行 ajax 调用,会话超时后将显示 xml 响应,而不是呈现的错误页面。

如果使用PrimeExceptionHandler,也会出现类似的错误。如果两个异常处理程序都被删除,浏览器中类似的错误输出和异常就会出现。请参阅 EDIT 浏览器输出。

EDIT 2如果web.xml中的行改为“JSP”登录

        <form-login-page>/login/login.jsp</form-login-page>
        <form-error-page>/login/login.jsp</form-error-page>

那么 AjaxExceptionHandler 不会被调用。

login.xhtml 与 https://stackoverflow.com/a/2207147/2023524 非常相似。仅适用于 RequestScope 和无状态视图。

在浏览器中输出

<partial-response id="j_id1"><changes><update id="javax.faces.ViewRoot"><html xmlns="http://www.w3.org/1999/xhtml">
            text of ErrorHandlerViewExpired.xhtml ...

</html></update><update id="j_id1:javax.faces.ViewState:0">stateless</update></changes></partial-response>

web.xml:

<login-config>
    <auth-method>FORM</auth-method>
    <realm-name>app</realm-name>
    <form-login-config>
        <form-login-page>/login/login.xhtml</form-login-page>
        <form-error-page>/login/login.xhtml</form-error-page>
    </form-login-config>
</login-config>
<error-page>
    <error-code>500</error-code>
    <location>/errors/errorHandlerWeb.xhtml?faces-redirect=true</location>
</error-page>
<error-page>
    <exception-type>javax.faces.application.ViewExpiredException</exception-type>
    <location>/errors/errorHandlerViewExpired.xhtml?faces-redirect=true</location>
</error-page>
<error-page>
    <exception-type>java.lang.Exception</exception-type>
    <location>/errors/errorHandlerProg.xhtml</location>
</error-page>

faces-config.xml:

<factory>
   <exception-handler-factory>
      org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory
   </exception-handler-factory>
</factory>

控制台:

FullAjaxExceptionHandler: An exception occurred during processing JSF ajax request. Error page '/errors/errorHandlerViewExpired.xhtml?faces-redirect=true' will be shown.: javax.faces.application.ViewExpiredException: viewId:/login/login.xhtml - Ansicht /login/login.xhtml konnte nicht wiederhergestellt werden.
    at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:212) [jsf-impl-2.2.11.jar:2.2.11]
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) [jsf-impl-2.2.11.jar:2.2.11]

编辑

在没有 ajaxExceptionHandler 的情况下在浏览器中输出

<partial-response id="j_id1">
  <redirect url="/app/pageWithAjax.jsf"/>
    <error>
    <error-name>class javax.faces.application.ViewExpiredException</error-name>
     <error-message>viewId:/login/login.xhtml - Ansicht /login/login.xhtml konnte nicht wiederhergestellt werden.
     </error-message></error></partial-response>

【问题讨论】:

  • 这是一个有登录限制的页面吗?您如何验证用户身份?春季安全?无论如何,是身份验证框架错误地重新执行 JSF ajax 请求,而不是创建新的 GET 请求。
  • 页面受限于“FORM”认证。用户通过 JSF 登录支持 bean 进行身份验证。 (标准 Java EE)登录视图是“login/login.xhtml”。那么麻烦的应该是WildFly。另请参阅更新
  • 我重新阅读了这个问题,对确切的用例有点困惑。我是否理解正确:1)您在浏览器中打开了一个受限的 JSF 页面。 2)会话在后台过期。 3) 您在该受限 JSF 页面上触发 ajax 请求。 4) 你在浏览器中看到 内容为 errorHandlerViewExpired.xhtml 纯文本。这个顺序正确吗?
  • 是的,你是对的。我打开受限页面/app/pagesWithAjax.xhtml。该页面在浏览器中打开,会话超时后,我单击p:dataTable,并在行上显示 ajax 事件。然后在浏览器中我看到 .
  • 这确实不是预期的行为。我稍后会尝试重现。

标签: jsf primefaces omnifaces


【解决方案1】:

此处描述了 Omnifaces 的正确解决方案:

https://stackoverflow.com/a/35843836/2023524


这是针对一种具体情况的解决方案,仅当用户使用 Java EE 登录并希望重定向到错误页面而不是登录页面时。

import java.io.IOException;

import javax.faces.FacesException;
import javax.faces.application.ViewExpiredException;
import javax.faces.context.ExceptionHandler;
import javax.faces.context.FacesContext;

import org.omnifaces.exceptionhandler.FullAjaxExceptionHandler;
import org.omnifaces.util.Faces;

public class CustomExceptionViewExpiredHandler extends FullAjaxExceptionHandler{

    public CustomExceptionViewExpiredHandler(ExceptionHandler wrapped) {
        super(wrapped);
    }

    @Override
    public void handle() throws FacesException {
            boolean b = handleViewExpiredException(Faces.getContext());
            if (!b)
                return;
            super.handle();

    }

    private boolean handleViewExpiredException (FacesContext context){
        if (context == null || !context.getPartialViewContext().isAjaxRequest()) {
            return false; // Not an ajax request.
        }

        //Test user Principal, java authentication
        if (Faces.getSession() == null || Faces.getRequest().getUserPrincipal() == null){
            try {
                String errorPageLocation = findErrorPageLocation(context, new SomeSessionExpiredException());

                Faces.redirect(Faces.getRequestContextPath() + errorPageLocation);
                Faces.responseComplete();
                return false;
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            }
        }
        return true;
    }
}

【讨论】:

    猜你喜欢
    • 2015-04-03
    • 2020-12-15
    • 1970-01-01
    • 2013-06-10
    • 2010-11-03
    • 2016-06-20
    • 2015-11-22
    • 2012-03-11
    相关资源
    最近更新 更多