错误页面上的错误报告表单

时间:2012-11-12 13:53:56

标签: ajax jsf exception-handling omnifaces

我在JBoss 7.1和Richfaces 4.1中有一个JSF Web应用程序。我尝试在web.xml中配置自定义错误页面,但遇到了问题,这对AJAX请求不起作用。作为一种解决方案,我尝试使用Omnifaces FullAjaxExceptionHandler来显示错误页面。

但是我想添加一个表单,允许用户输入其他信息并将其作为电子邮件发送给我。问题是在错误页面上,提交按钮不起作用。当我点击它时,错误页面刚刚重新加载。在下一次单击时,一切都按预期工作。

h:commandlinks在错误页面模板中的小菜单中出现同样的问题。

我对JSF很新,所以我真的不知道为什么会发生这种情况以及如何修复它。或者有更好的方法来实现这一目标吗?

1 个答案:

答案 0 :(得分:1)

这与JSF spec issue 790有关,其归结为ajax更新某些组件,而这些组件又包含一个或多个<h:form>组件,无法正确更新这些表单的新视图状态标识符。

此问题已在即将推出的JSF 2.2中修复,但在此之前,您将使用以下基于JavaScript的解决方法。

jsf.ajax.addOnEvent(function(data) {
    if (data.status == "success") {
        var viewState = getViewState(data.responseXML);

        if (viewState) {
            for (var i = 0; i < document.forms.length; i++) {
                var form = document.forms[i];

                if (!hasViewState(form)) {
                    createViewState(form, viewState);
                }
            }
        }
    }
});

function getViewState(responseXML) {
    var updates = responseXML.getElementsByTagName("update");

    for (var i = 0; i < updates.length; i++) {
        var update = updates[i];

        if (update.getAttribute("id") == "javax.faces.ViewState") {
            return update.firstChild.nodeValue;
        }
    }

    return null;
}

function hasViewState(form) {
    for (var i = 0; i < form.elements.length; i++) {
        if (form.elements[i].name == "javax.faces.ViewState") {
            return true;
        }
    }

    return false;
}

function createViewState(form, viewState) {
    var hidden;

    try {
        hidden = document.createElement("<input name='javax.faces.ViewState'>"); // IE6-8.
    } catch(e) {
        hidden = document.createElement("input");
        hidden.setAttribute("name", "javax.faces.ViewState");
    }

    hidden.setAttribute("type", "hidden");
    hidden.setAttribute("value", viewState);
    hidden.setAttribute("autocomplete", "off");
    form.appendChild(hidden);
}

只需将其<h:outputScript name="some.js" target="head">包含在错误页面的<h:body>中即可。如果您无法保证该网页使用的是JSF <f:ajax>,那么您可能需要在if (typeof jsf !== 'undefined')来电之前添加额外的jsf.ajax.addOnEvent()支票。

JSF组件库PrimeFaces已经在其核心ajax引擎中解决了这个问题,所以如果你碰巧已经使用它,你可能想要用PrimeFaces替换所有<f:ajax>链接/按钮。

另见: