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

查看:226
本文介绍了为什么要使用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.

所以,基本上:

So, basically:

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异常的正确方法是什么? a>和此博客:完整的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天全站免登陆