我在JBoss 7.1和Richfaces 4.1中有一个JSF Web应用程序。我尝试在web.xml中配置自定义错误页面,但遇到了问题,这对AJAX请求不起作用。作为一种解决方案,我尝试使用Omnifaces FullAjaxExceptionHandler来显示错误页面。
但是我想添加一个表单,允许用户输入其他信息并将其作为电子邮件发送给我。问题是在错误页面上,提交按钮不起作用。当我点击它时,错误页面刚刚重新加载。在下一次单击时,一切都按预期工作。
h:commandlinks在错误页面模板中的小菜单中出现同样的问题。
我对JSF很新,所以我真的不知道为什么会发生这种情况以及如何修复它。或者有更好的方法来实现这一目标吗?
答案 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>
链接/按钮。