【问题标题】:Capture and log / notify unhandled exceptions in a JSF based application在基于 JSF 的应用程序中捕获和记录/通知未处理的异常
【发布时间】:2015-08-08 11:14:05
【问题描述】:

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

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

【问题讨论】:

    标签: jsf logging exception-handling


    【解决方案1】:

    添加一个实现Thread.UncaughtExceptionHandler 的类。但该方法没有被触发

    在由 Java EE Web 应用程序管理的 HTTP 请求线程中通常没有未捕获的异常,因为服务器最终会捕获来自 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>
    

    另见:

    【讨论】:

    • 嗨 BalusC,首先,我很喜欢你的回答,如此清晰,如此有启发性......这非常有效,你所说的一切都很有道理......非常感谢你的时间和你的好答案! ... 将帖子标记为已解决。祝你有美好的一天!
    猜你喜欢
    • 1970-01-01
    • 2013-05-16
    • 1970-01-01
    • 2010-11-08
    • 1970-01-01
    • 2014-09-02
    • 1970-01-01
    • 2010-11-03
    • 1970-01-01
    相关资源
    最近更新 更多