AbortProcessingException在服务器日志中留下堆栈跟踪,如何禁用它?

时间:2015-03-03 22:23:28

标签: jsf exception logging jsf-2 actionlistener

页面上有commandButton异步调用某些服务,当用户单击按钮时,我想通过检查数据库中的特殊配置来验证服务可用性。此配置可以每分钟更新一次。因此,如果该服务不可用,则不应执行action commandButton

因此,根据Differences between action and actionListener,我检查actionListener中的服务可用性,并在服务不可用时抛出AbortProcessingException。因此将跳过action

这样可以正常工作,但它会在服务器的日志中留下堆栈跟踪。我不想要这样的行为。是否可以以这样的方式处理异常,即不会在服务器日志中留下标记,就像抛出ValidatorException时一样?我使用OmniFaces FullAjaxExceptionHandler,如果相关的话。

1 个答案:

答案 0 :(得分:2)

您可以使用自定义异常处理程序禁止日志记录。当您正在使用OmniFaces FullAjaxExceptionHandler时,您可以更好地扩展它。在handle()方法中,检查是否存在例外,以及它是AbortProcessingException的实例。如果是这样,那么只需忽略它并直接从异常处理程序返回。

public class YourExceptionHandler extends FullAjaxExceptionHandler {

    public YourExceptionHandler(ExceptionHandler wrapped) {
        super(wrapped);
    }

    @Override
    public void handle() throws FacesException {
        Iterator<ExceptionQueuedEvent> events = getUnhandledExceptionQueuedEvents().iterator();

        if (events.hasNext() && events.next().getContext().getException() instanceof AbortProcessingException) {
            return; // Ignore (and don't log).
        }

        super.handle(); // Continue to FullAjaxExceptionHandler.
    }

}

围绕它创建一个工厂:

public class YourExceptionHandlerFactory extends ExceptionHandlerFactory {

    private ExceptionHandlerFactory wrapped;

    public YourExceptionHandlerFactory(ExceptionHandlerFactory wrapped) {
        this.wrapped = wrapped;
    }

    @Override
    public ExceptionHandler getExceptionHandler() {
        return new YourExceptionHandler(getWrapped().getExceptionHandler());
    }

    @Override
    public ExceptionHandlerFactory getWrapped() {
        return wrapped;
    }

}

要使其运行,请按照常规方式faces-config.xml将其注册为工厂,替换FullAjaxExceptionHandlerFactory

<factory>
    <exception-handler-factory>com.example.YourExceptionHandlerFactory</exception-handler-factory>
</factory>