为什么使用 JSF ExceptionHandlerFactory 而不是 <error-page>重定向? [英] Why use a JSF ExceptionHandlerFactory instead of <error-page> redirection?

查看:15
本文介绍了为什么使用 JSF ExceptionHandlerFactory 而不是 <error-page>重定向?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

到目前为止,我遇到的所有 ExceptionHandlerFactory 示例都将用户重定向到 viewExpired.jsf 页面,以防出现 ViewExpiredException被抓住了:

All of the ExceptionHandlerFactory examples I have come across so far redirect a user to a viewExpired.jsf page in the event that a ViewExpiredException is caught:

public class ViewExpiredExceptionExceptionHandler extends ExceptionHandlerWrapper {
    private ExceptionHandler wrapped;

    public ViewExpiredExceptionExceptionHandler(ExceptionHandler wrapped) {
        this.wrapped = wrapped;
    }

    @Override
    public ExceptionHandler getWrapped() {
        return this.wrapped;
    }

    @Override
    public void handle() throws FacesException {
        for (Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator(); i.hasNext();) {
            ExceptionQueuedEvent event = i.next();
            ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource();

            Throwable t = context.getException();
            if (t instanceof ViewExpiredException) {
                ViewExpiredException vee = (ViewExpiredException) t;
                FacesContext facesContext = FacesContext.getCurrentInstance();
                Map<String, Object> requestMap = facesContext.getExternalContext().getRequestMap();
                NavigationHandler navigationHandler = facesContext.getApplication().getNavigationHandler();
                try {
                    // Push some useful stuff to the request scope for use in the page
                    requestMap.put("currentViewId", vee.getViewId());
                    navigationHandler.handleNavigation(facesContext, null, "/viewExpired");
                    facesContext.renderResponse();
                } finally {
                    i.remove();
                }
            }
        }

        // At this point, the queue will not contain any ViewExpiredEvents. Therefore, let the parent handle them.
        getWrapped().handle();
    }
}

在我看来,以下简单的 web.xml 配置基本相同,而且简单得多:

It seems to me that the following simple web.xml configuration is fundamentally the same and a lot simpler:

<error-page>
    <exception-type>javax.faces.application.ViewExpiredException</exception-type>
    <location>/viewExpired.jsf</location>
</error-page>

这就提出了一个问题——为什么要使用 ExceptionHandlerFactory?

This prompts the question - why would one use an ExceptionHandlerFactory?

推荐答案

这个特定的例子只做了一件有用的事情:它将视图 ID 保存为请求属性,以便你可以使用例如

The particular example does only one useful thing: it saves the view ID as a request attribute so that you can use for example

<h:link value="Go back to previous page" outcome="#{currentViewId}" />

但这并不是非常有用,因为原始请求 URI 已经可以通过 <error-page> 的默认请求属性 javax.servlet.error.request_uri.

But this is not tremendously useful as the raw request URI is already available by the <error-page>'s default request attribute javax.servlet.error.request_uri.

<h:outputLink value="#{requestScope['javax.servlet.error.request_uri']}">Go back to previous page</h:outputLink>

然而,自定义 ExceptionHandler 真正有用的一件事是它允许您在 ajax 请求期间处理异常.默认情况下,他们在客户端没有单一形式的有用反馈.只有在项目阶段设置为开发"的 Mojarra 中,您才会看到带有异常消息的纯 JavaScript 警报消息.但就是这样.在生产"阶段没有单一形式的反馈.使用自定义 ExceptionHandler,您将能够解析 web.xml 以查找错误页面位置,使用它创建一个新的 UIViewRoot 并强制JSF 将 ajax 渲染设置为 @all.

However one thing what a custom ExceptionHandler is really useful for is that it allows you to deal with exceptions during ajax requests. By default they have namely no single form of helpful feedback in the client side. Only in Mojarra with project stage set to "Development" you'll see a bare JavaScript alert message with the exception message. But that's it. There is no single form of feedback in "Production" stage. With a custom ExceptionHandler you would be able to parse the web.xml to find the error page locations, create a new UIViewRoot with it and force JSF to set ajax rendering to @all.

所以,基本上:

String errorPageLocation = "/WEB-INF/errorpages/500.xhtml";
context.setViewRoot(context.getApplication().getViewHandler().createView(context, errorPageLocation));
context.getPartialViewContext().setRenderAll(true);
context.renderResponse();

另见这个相关问题:处理 AJAXified 组件的 JSF 2.0 异常的正确方法是什么? 和此博客:完整的 Ajax 异常处理程序.

See also this related question: What is the correct way to deal with JSF 2.0 exceptions for AJAXified components? and this blog: Full Ajax Exception Handler.

这篇关于为什么使用 JSF ExceptionHandlerFactory 而不是 &lt;error-page&gt;重定向?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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