JSF ajax 请求中的异常处理
Posted
技术标签:
【中文标题】JSF ajax 请求中的异常处理【英文标题】:Exception handling in JSF ajax requests 【发布时间】:2022-01-07 01:42:19 【问题描述】:在处理 JSF ajax 请求时抛出异常时,如何处理异常并访问堆栈跟踪?现在,当 JSF 项目阶段设置为 Development 时,我只在 javascript 警报中获得异常类名称和消息。更糟糕的是,当 JSF 项目阶段设置为生产时,没有任何视觉反馈,并且服务器日志没有显示有关异常的任何信息。
如果相关,我在 Netbeans 中使用 GlassFish。
【问题讨论】:
您想在异步请求期间在网页上显示完整的异常堆栈跟踪吗? 没有。我在页面上有一个这个问题在OmniFaces FullAjaxExceptionHandler
showcase 中是已知的并得到了充实。
默认情况下,当 JSF ajax 请求期间发生异常时,无论操作是否成功执行,最终用户都不会得到任何形式的反馈。在 Mojarra 中,只有当项目阶段设置为 Development 时,最终用户才会看到仅包含异常类型和消息的纯 JavaScript 警报。
技术原因是异步请求(阅读:Ajax 请求)默认不返回同步响应(阅读:整页)。相反,它们返回小指令和部分如何更新已打开页面的 HTML DOM 树。当异常发生时,那么这些指令基本上是完全不存在的。相反,会发回一些错误信息。您通常可以在 Ajax 组件的 onerror
属性中处理它们,例如显示警报或执行window.location
更改。至少,这是 JSF 对您的期望。
为了捕获和记录异常并选择性地更改整个响应,您基本上需要创建一个自定义ExceptionHandler
。不幸的是,标准 JSF 没有提供默认的开箱即用(至少,不是一个明智的)。在您的自定义异常处理程序中,您将能够处理导致所有问题的 Exception
实例。
这是一个启动示例:
public class YourExceptionHandler extends ExceptionHandlerWrapper
private ExceptionHandler wrapped;
public YourExceptionHandler(ExceptionHandler wrapped)
this.wrapped = wrapped;
@Override
public void handle() throws FacesException
FacesContext facesContext = FacesContext.getCurrentInstance();
for (Iterator<ExceptionQueuedEvent> iter = getUnhandledExceptionQueuedEvents().iterator(); iter.hasNext();)
Throwable exception = iter.next().getContext().getException(); // There it is!
// Now do your thing with it. This example implementation merely prints the stack trace.
exception.printStackTrace();
// You could redirect to an error page (bad practice).
// Or you could render a full error page (as OmniFaces does).
// Or you could show a FATAL faces message.
// Or you could trigger an oncomplete script.
// etc..
getWrapped().handle();
@Override
public ExceptionHandler getWrapped()
return wrapped;
为了让它运行,创建一个自定义ExceptionHandlerFactory
,如下所示:
public class YourExceptionHandlerFactory extends ExceptionHandlerFactory
private ExceptionHandlerFactory parent;
public YourExceptionHandlerFactory(ExceptionHandlerFactory parent)
this.parent = parent;
@Override
public ExceptionHandler getExceptionHandler()
return new YourExceptionHandler(parent.getExceptionHandler());
需要在faces-config.xml
注册如下:
<factory>
<exception-handler-factory>com.example.YourExceptionHandlerFactory</exception-handler-factory>
</factory>
或者,您可以继续使用 OmniFaces 之一。它将完全透明地确保异步请求期间的异常与同步请求期间的异常行为相同,使用web.xml
中的<error-page>
配置。
另见:
Why FullAjaxExceptionHandler does not simply perform an ExternalContext#redirect()? Authorization redirect on session expiration does not work on submitting a JSF form, page stays the same【讨论】:
以上是关于JSF ajax 请求中的异常处理的主要内容,如果未能解决你的问题,请参考以下文章