会话超时后的Ajax请求显示<partial-response>

时间:2016-03-04 13:30:53

标签: jsf primefaces omnifaces

Omnifaces 2.0,Primefaces 5,wildFly 8.2

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

如果使用PrimeExceptionHandler,则会出现类似错误。如果删除了两个除外处理程序,则浏览器中出现类似的错误输出并出现异常。请参阅 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>

1 个答案:

答案 0 :(得分:0)

这里描述了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;
    }
}