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

AbortProcessingException leaves stack trace in server log, how to disable this?

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

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

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

您可以使用自定义异常处理程序抑制日志记录。由于您目前正在使用 OmniFaces FullAjaxExceptionHandler,您最好扩展它。在 handle() 方法中,检查是否有异常,是否是 AbortProcessingException 的实例。如果是这样,则忽略它并直接从异常处理程序 return。

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>