添加一个实现的类Thread.UncaughtExceptionHandler
。但该方法没有被触发
在 Java EE Web 应用程序管理的 HTTP 请求线程中通常无法捕获未捕获的异常,因为服务器最终会捕获来自 Web 应用程序的任何异常,并在 HTTP 500 错误页面中出现同步 HTTP 请求时将其显示出来(以防异步(ajax)请求,这又取决于框架)。此外,如果确实有一个未捕获的异常逃过了服务器的注意,它就会杀死服务器的运行时线程,导致整个服务器停止。这显然不是理想的现实场景。
JSF 为您提供ExceptionHandler http://docs.oracle.com/javaee/7/api/javax/faces/context/ExceptionHandler.html用于处理这些异常并在必要时控制它们的 API。
这是一个启动示例:
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. As per the question, you want to log it using log4j.
logger.error("An exception occurred!", exception);
}
getWrapped().handle();
}
@Override
public ExceptionHandler getWrapped() {
return wrapped;
}
}
为了让它运行,创建一个自定义ExceptionHandlerFactory https://docs.oracle.com/javaee/7/api/javax/faces/context/ExceptionHandlerFactory.html如下:
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>
也可以看看:
- JSF ajax 请求中的异常处理 https://stackoverflow.com/questions/27526753/exception-stack-trace-in-jsf-ajax-requests