JSF ajax请求中的异常处理

时间:2022-09-13 20:01:25

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.

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

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

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

1 个解决方案

#1


10  

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

这个问题在OmniFaces FullAjaxExceptionHandler展示中已知并充实。

Basically, you need to create a custom ExceptionHandler as standard JSF doesn't provide one out the box (at least, not a sensible one). Therein you will be able to get hands on the Exception instance causing all the trouble.

基本上,你需要创建一个自定义ExceptionHandler作为标准JSF不提供一个开箱即用(至少,不是一个明智的)。在那里,您将能够获得Exception实例,从而导致所有麻烦。

Here's a kickoff example:

这是一个启动示例:

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;
    }

}

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

要使其运行,请按如下方式创建自定义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());
    }

}

Which needs to be registered in faces-config.xml as follows:

需要在faces-config.xml中注册,如下所示:

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

See also:

#1


10  

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

这个问题在OmniFaces FullAjaxExceptionHandler展示中已知并充实。

Basically, you need to create a custom ExceptionHandler as standard JSF doesn't provide one out the box (at least, not a sensible one). Therein you will be able to get hands on the Exception instance causing all the trouble.

基本上,你需要创建一个自定义ExceptionHandler作为标准JSF不提供一个开箱即用(至少,不是一个明智的)。在那里,您将能够获得Exception实例,从而导致所有麻烦。

Here's a kickoff example:

这是一个启动示例:

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;
    }

}

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

要使其运行,请按如下方式创建自定义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());
    }

}

Which needs to be registered in faces-config.xml as follows:

需要在faces-config.xml中注册,如下所示:

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

See also: