Java Primefaces p:ajaxStatus onerror未调用

Java Primefaces p:ajaxStatus onerror未调用,java,jsf,glassfish,primefaces,Java,Jsf,Glassfish,Primefaces,我正在尝试使用glassfish 3.1上的primefaces 2.2.1处理ajax调用上的ViewExpiredException异常。我的Ajax状态如下: <p:ajaxStatus id="ajaxStatus" onstart="startAjaxDisplay()" onerror="ajaxErrorHandler()" oncomplete="endAjaxDis

我正在尝试使用glassfish 3.1上的primefaces 2.2.1处理ajax调用上的ViewExpiredException异常。我的Ajax状态如下:

  <p:ajaxStatus id="ajaxStatus"  
                onstart="startAjaxDisplay()" 
                onerror="ajaxErrorHandler()" 
                oncomplete="endAjaxDisplay()"/> 
<?xml version="1.0" encoding="UTF-8"?>
<partial-response>
  <error>
    <error-name>class javax.faces.application.ViewExpiredException</error-name>
    <error-message><![CDATA[viewId:/index.xhtml - View /index.xhtml could not be restored.]]></error-message>
  </error>
  <changes>
    <extension primefacesCallbackParam="validationFailed">{"validationFailed":false}</extension>
  </changes>
</partial-response>

按预期调用onstart和oncomplete。我知道ajaxErrorHandler()可以工作,因为我把它放在了oncomplete中,它被调用了。它现在所做的只是弹出一个警报()。我设置了测试,服务器的响应如下所示:

  <p:ajaxStatus id="ajaxStatus"  
                onstart="startAjaxDisplay()" 
                onerror="ajaxErrorHandler()" 
                oncomplete="endAjaxDisplay()"/> 
<?xml version="1.0" encoding="UTF-8"?>
<partial-response>
  <error>
    <error-name>class javax.faces.application.ViewExpiredException</error-name>
    <error-message><![CDATA[viewId:/index.xhtml - View /index.xhtml could not be restored.]]></error-message>
  </error>
  <changes>
    <extension primefacesCallbackParam="validationFailed">{"validationFailed":false}</extension>
  </changes>
</partial-response>

类javax.faces.application.ViewExpiredException
{“validationFailed”:false}

这一切都是意料之中的,只是onerror没有接到电话。我是否误解了这是如何工作的?

不会调用OneError处理程序,因为ViewExpiredException不是AJAX错误,而是在构建已经过期(会话过期)的视图期间的JSF。 PrimeFaces ajax组件不能将这种情况作为错误处理

在我的解决方案(JSF2+PrimeFaces3)中,我研究来自服务器的ajax响应并搜索JSF错误消息。请参见下面最简单的示例:

<h:head>
    <title>Facelet Title</title>
    <script language="javasript" type="text/javascript">
        function handleAjaxRequest(xhr, status, args){
            var xmlDoc = xhr.responseXML;
            errorNodes = xmlDoc.getElementsByTagName('error-name');
            if (errorNodes.length == 0) return;
            errorName = errorNodes[0].childNodes[0].nodeValue;
            switch (errorName) {
                case 'class javax.faces.application.ViewExpiredException': 
                    alert ('Session expired, redirecting to login page!');

                    window.location.href = 'login.xhtml';
                break;
            }
        }    
    </script>
</h:head>

<h:body>
    <h:form id="frmText">
        Enter the value: <p:inputText value="#{bean.text}" />
        <p:commandButton value="Enter" update="frmText" 
                         oncomplete="handleAjaxRequest(xhr, status, args);"/>
        <p:separator />
        The entered text is: <h:outputText value="#{bean.text}" style="font-weight: 900"/>
    </h:form>
</h:body>

Facelet标题
函数handleAjaxRequest(xhr、状态、参数){
var xmlDoc=xhr.responseXML;
errorNodes=xmlDoc.getElementsByTagName('error-name');
if(errorNodes.length==0)返回;
errorName=errorNodes[0]。childNodes[0]。nodeValue;
开关(错误名称){
案例“class javax.faces.application.ViewExpiredException”:
警报('会话已过期,重定向到登录页!');
window.location.href='login.xhtml';
打破
}
}    
输入值:
输入的文本是:

您如何模拟错误?您是否有理由抛出
ViewExpiredException
,或者您只是认为应该在某个地方调用它。我问这个问题是因为我的想法是,如果在命名错误之前出现其他错误,而
ViewExpiredException
就是因为没有调用它。在这种情况下,我从facesContext.getExternalContext().getSession()获取会话,然后对其调用invalidate()。调用它的方法是从其他浏览器窗口调用的。我还尝试过重启服务器和设置非常短的会话超时。我的“答案”是一个关于这一点的问题。您是否100%确定所述invalidate()方法完全抛出所述的
ViewExpiredException
而不抛出其他内容?我的假设是,它可能会抛出一些其他的,这就是为什么你看不到它。这是我脑海中出现的一个假设,不是一个科学证明的答案。无效不会抛出任何东西。这是会话无效后的下一个ajax请求,它创建了带有错误的部分响应。Primefaces似乎不认为这是一个错误。我最终做了本质上相同的事情,但在后面使用异常处理程序发送重定向,而不是在客户端捕获重定向。