JSF ajax 请求中的异常处理 [英] Exception handling in JSF ajax requests

查看:33
本文介绍了JSF ajax 请求中的异常处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How do I handle the exception and access the stack trace when an exception is thrown while processing a JSF ajax request? Right now, I only get the exception class name and message in a JavaScript alert when JSF project stage is set to Development. Even worse, there's no visual feedback whatsoever when JSF project stage is set to Production, and the server log doesn't show any information about the exception.

如果相关,我将在 Netbeans 中使用 GlassFish.

If that's relevant, I'm using GlassFish in Netbeans.

推荐答案

这个问题是众所周知的,并且在 OmniFaces FullAjaxExceptionHandler 展示.

This problem is known and fleshed out in among others the OmniFaces FullAjaxExceptionHandler showcase.

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

By default, when an exception occurs during a JSF ajax request, the enduser would not get any form of feedback if the action was successfully performed or not. In Mojarra, only when the project stage is set to Development, the enduser would see a bare JavaScript alert with only the exception type and message.

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

The technical reason is that asynchronous requests (read: Ajax requests) by default don't return a synchronous response (read: a full page). Instead, they return small instructions and parts how to update the HTML DOM tree of the already-opened page. When an exception occurs, then these instructions are basically fully absent. Instead, some error information is sent back. You can usually handle them in the onerror attribute of the Ajax component and e.g. display an alert or perhaps perform a window.location change. At least, this is what JSF expected from you.

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

In order to catch and log the exception and optionally change the whole response, you basically need to create a custom ExceptionHandler. Standard JSF unfortunately doesn't provide a default one out the box (at least, not a sensible one). In your custom exception handler you will be able to get hands on the Exception instance causing all the trouble.

这是一个启动示例:

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 如下:

In order to get it to run, create a custom ExceptionHandlerFactory as follows:

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 中.

Alternatively, you can go ahead using the OmniFaces one. It will fully transparently make sure that exceptions during asynchronous requests behave the same as exceptions during synchronous requests, using <error-page> configuration in web.xml.

这篇关于JSF ajax 请求中的异常处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆