在基于JSF的应用程序中捕获并记录/通知未处理的异常

时间:2015-05-26 16:42:00

标签: jsf logging exception-handling

我想使用log4j检查并记录我的JSF Web应用程序中的所有未处理的异常。我阅读了这篇文章Log runtime Exceptions in Java using log4j并添加了一个实现Thread.UncaughtExceptionHandler的类。但是方法没有解雇。

实现这一目标的正确方法是什么?

1 个答案:

答案 0 :(得分:5)

在Java EE Web应用程序中通常没有未捕获的异常,因为服务器最终捕获来自Web应用程序的任何异常,并在HTTP 500错误页面中显示同步HTTP请求(在异步(ajax)请求的情况,这反过来依赖于框架)。此外,如果真的有一个未被捕获的异常逃脱了服务器的注意,它将杀死服务器的运行时线程,导致整个服务器停止。这显然不是一个理想的现实世界。

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>

另见: