我有一个CustomExceptionHandler,我想从中显示一个模态对话框,使用Primefaces对话框框架从用户获取一些信息。
当我故意引起空指针异常时,CustomExceptionHandler#handle
方法正在按预期调用。如果我直接从xhtml页面上的p:commandButton的actionListener调用对话框的.xhtml页面,我就可以显示对话框的.xhtml页面并与之交互(这两种情况都启用和禁用了ajax)。
当我在导致NPE的页面上调用p:commandButton(禁用ajax以消除使场景复杂化的可能的ajax错误)时,在CustomExceptionHandler#handle
生成日志消息之前/之后都没有显示对话框页面。然而,窗口像被刷新一样闪烁。
public class CustomExceptionHandler
extends ExceptionHandlerWrapper
{
private ExceptionHandler wrapped;
public CustomExceptionHandler(ExceptionHandler wrapped)
{
this.wrapped = wrapped;
}
@Override
public ExceptionHandler getWrapped()
{
return wrapped;
}
@Override
public void handle()
throws FacesException
{
Iterator<ExceptionQueuedEvent> iterator = getUnhandledExceptionQueuedEvents().iterator();
while (iterator.hasNext()) {
boolean removeError = false;
Throwable t = iterator.next().getContext().getException();
while (t.getCause() != null)
t = t.getCause();
if (t instanceof NullPointerException) {
Logging.devLogger.warn("NPE exception handler before dialog");
Map<String, Object> options = new HashMap<>();
options.put("modal", true);
String page = "/home/dialogs/exceptionDialog.xhtml";
RequestContext.getCurrentInstance().openDialog(page, options, null);
Logging.devLogger.warn("NPE exception handler after dialog");
removeError = true;
} // TBD: other cases and refactoring ....
if (removeError) iterator.remove();
}
getWrapped().handle();
}
}
RequestContext....openDialog()
调用在处理异常和通过commandButton直接打开对话框时是相同的。我已经确定了异常对话框(视图范围)的支持bean在异常情况下打开对话框时构造,但在处理异常时打开时不构造(未调用@PostConstruct方法)。
我如何改变异常处理的方式,使对话框按照预期的方式运行?我使用Mojarra 2.2.5, Primefaces 4.0, Glassfish 4.0。
我正在使用PrimeFaces 5.2,我已经用其他方式解决了这个问题。
显示对话框,我已经创建了错误对话框在我的模板名为"errorDialog"和显示它通过我的CustomExceptionHandler我已经使用,这个命令
RequestContext.getCurrentInstance().execute("PF('errorDialog').show();");
你不能使用下面的命令,因为已经有一个异常,所以你可以呈现对话框。
RequestContext.getCurrentInstance().openDialog(page, options, null);
关于@PostConstruct方法的异常处理,我使用:
@PostConstruct
private void init() {
try {
initController();
} catch (Exception ex) {
logger.error(ex, null);
//Show the error dialog
MyUtil.openErrorDialog();
}
}
注意:我仍然有一个问题,当一个异常(错误500)发生并由应用服务器而不是我的CustomHandlerClass处理时,我无法显示对话框,因为已经有一个重定向的应用服务器。