在基于 JSF 的应用程序中捕获并记录/通知未处理的异常
Capture and log / notify unhandled exceptions in a JSF based application
我想使用 log4j 检查并记录我的 JSF Web 应用程序中所有未处理的异常。我阅读了这个 post Log runtime Exceptions in Java using log4j 并添加了一个实现 Thread.UncaughtExceptionHandler
的 class。但该方法未触发。
实现这一目标的正确方法是什么?
add a class that implements Thread.UncaughtExceptionHandler
. but the method is not fired
在由 Java EE Web 应用程序管理的 HTTP 请求线程中通常没有未捕获的异常,因为服务器最终捕获来自 Web 应用程序的任何异常并在同步 HTTP 请求的情况下显示它在 HTTP 500 错误页面中(在异步 (ajax) 请求的情况下,这又取决于框架)。此外,如果真的有一个未捕获的异常逃过了服务器的注意,它会杀死服务器的 运行time 线程,导致整个服务器停止。这显然不是理想的现实世界场景。
JSF 为您提供 ExceptionHandler
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
如下:
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>
另请参阅:
- Exception handling in JSF ajax requests
我想使用 log4j 检查并记录我的 JSF Web 应用程序中所有未处理的异常。我阅读了这个 post Log runtime Exceptions in Java using log4j 并添加了一个实现 Thread.UncaughtExceptionHandler
的 class。但该方法未触发。
实现这一目标的正确方法是什么?
add a class that implements
Thread.UncaughtExceptionHandler
. but the method is not fired
在由 Java EE Web 应用程序管理的 HTTP 请求线程中通常没有未捕获的异常,因为服务器最终捕获来自 Web 应用程序的任何异常并在同步 HTTP 请求的情况下显示它在 HTTP 500 错误页面中(在异步 (ajax) 请求的情况下,这又取决于框架)。此外,如果真的有一个未捕获的异常逃过了服务器的注意,它会杀死服务器的 运行time 线程,导致整个服务器停止。这显然不是理想的现实世界场景。
JSF 为您提供 ExceptionHandler
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
如下:
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>
另请参阅:
- Exception handling in JSF ajax requests