对于Ajax请求,FullAjaxExceptionHandler不会重定向到错误页面

时间:2013-09-03 16:19:33

标签: ajax jsf-2 primefaces error-handling omnifaces

我知道这个问题上有很多问题,但几乎所有问题都建议添加以下代码,因为FullAjaxExceptionHandler上面还有另一层发送普通重定向而不是进行Ajax重定向(参见{ {3}}):

if ("partial/ajax".equals(request.getHeader("Faces-Request"))) {
// JSF ajax request. Return special XML response which instructs JavaScript that it should in turn perform a redirect.
response.setContentType("text/xml");
response.getWriter()
    .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
    .printf("<partial-response><redirect url=\"%s\"></redirect></partial-response>", loginURL);
} else {
    // Normal request. Perform redirect as usual.
    response.sendRedirect(loginURL);
}

我的问题是我只是配置Omnifaces的FullAjaxExceptionHandler来完成所有错误处理,我没有Spring Security或容器管理的安全性,在FullAjaxExceptionHandler可以执行此操作之前拦截请求。我可以断点进入FullAjaxExceptionHandler并看到当执行以下代码行时,我的错误页面仍未被重定向。

String viewId = Faces.normalizeViewId(errorPageLocation);
ViewHandler viewHandler = context.getApplication().getViewHandler();
UIViewRoot viewRoot = viewHandler.createView(context, viewId);
context.setViewRoot(viewRoot);
context.getPartialViewContext().setRenderAll(true);
        ...
    context.renderResponse();

相反,发生异常的Ajax请求在其响应主体中有这个:

<?xml version='1.0' encoding='UTF-8'?>
    <partial-response>
        <changes>
            <update id="javax.faces.ViewRoot"><![CDATA[<html xmlns="http://www.w3.org/1999/xhtml">... html of error page here ... </html>]]></update>
            <update id="javax.faces.ViewState"><![CDATA[-3527653129719750158:5595502883804776498]]></update>
        </changes>
    </partial-response>

看起来FullAjaxExceptionHandler没有做它应该做的事情,或者我错过了什么?

更新

附加浏览器JS输出控制台屏幕上限。JS output console

问题已识别

原来我的错误页面的HTML格式不正确,它包含以下代码段,导致浏览器中的标记错误不匹配:

<script type="text/javascript">
//<![CDATA[
scrollTo(0, 0);
//]]>
</script>

这似乎过早地关闭了CDATA标签。这个HTML是<h:outputScript/>标记的结果,我删除了它,因为我不需要它。

2 个答案:

答案 0 :(得分:1)

ajax响应看起来完全正常,它包含整个错误页面文档的<update id="javax.faces.ViewRoot">,因此FullAjaxExceptionHandler正确地完成了它的工作。

在检索到ajax响应之后,更有可能在客户端或甚至在错误页面文档中导致您的具体问题。然后,JavaScript轮流解析ajax响应并相应地替换当前的HTML文档。检查浏览器的JavaScript控制台应该提供有关该步骤中问题的任何线索。在您的特定情况下,问题似乎是由CDATA呈现的内容周围的嵌套<h:outputScript>块引起的,这反过来导致JavaScript解析错误。

不幸的是,我无法用我手头的任何Mojarra版本重现这个问题。也许你的某个地方是自定义/第三方脚本渲染器,负责添加CDATA块。 CDATA返回PartialViewContext#isAjaxRequest()时,该脚本渲染器应跳过true块。如果您仍然无法弄明白,那么最好的办法是用普通的HTML <h:outputScript>替换<script>,或者甚至完全删除它 - 就像你最终做的那样。

答案 1 :(得分:1)

最初提出问题的很多年后,现在使用Wildfly 15,JSF 2.3,OmniFaces 3.2,我偶然发现了一个类似的问题:FullAjaxExceptionHandler的部分响应格式错误,以防ajax调用期间发生异常。原因是响应中嵌套了CDATA,从而注释掉了响应的一部分,从而导致XML解析错误。罪魁祸首似乎是JSF标签ui:debug。我删除了该声明,现在它可以按预期运行。