繁体   English   中英

JSF ajax 请求中的异常处理

[英]Exception handling in JSF ajax requests

在处理 JSF ajax 请求时抛出异常时,如何处理异常并访问堆栈跟踪? 现在,当 JSF 项目阶段设置为开发时,我只会在 JavaScript 警报中获得异常类名称和消息。 更糟糕的是,当 JSF 项目阶段设置为生产时,没有任何视觉反馈,并且服务器日志不显示有关异常的任何信息。

如果这是相关的,我在 Netbeans 中使用 GlassFish。

这个问题是众所周知的,并且在OmniFaces FullAjaxExceptionHandler展示中得到了充实。

默认情况下,当 JSF ajax 请求期间发生异常时,无论操作是否成功执行,最终用户都不会得到任何形式的反馈。 在 Mojarra 中,只有当项目阶段设置为开发时,最终用户才会看到仅包含异常类型和消息的纯 JavaScript 警报。

技术原因是异步请求(读取:Ajax 请求)默认不返回同步响应(读取:整页)。 相反,它们返回一些小说明和部分,如何更新已打开页面的 HTML DOM 树。 当发生异常时,那么这些指令基本上是完全没有的。 相反,一些错误信息被发回。 您通常可以在 Ajax 组件的onerror属性中处理它们,例如显示警报或执行window.location更改。 至少,这是 JSF 对您的期望。

为了捕获和记录异常并有选择地更改整个响应,您基本上需要创建一个自定义ExceptionHandler 不幸的是,标准 JSF 没有提供一个开箱即用的默认值(至少,不是一个合理的)。 在您的自定义异常处理程序中,您将能够处理导致所有麻烦的Exception实例。

这是一个启动示例:

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. This example implementation merely prints the stack trace.
            exception.printStackTrace();

            // You could redirect to an error page (bad practice).
            // Or you could render a full error page (as OmniFaces does).
            // Or you could show a FATAL faces message.
            // Or you could trigger an oncomplete script.
            // etc..
        }

        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>

或者,您可以继续使用 OmniFaces 之一。 它将完全透明地确保异步请求期间的异常行为与同步请求期间的异常行为相同,使用web.xml <error-page>配置。

也可以看看:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM