【发布时间】:2011-07-13 19:07:14
【问题描述】:
我很难完全理解 JSF 2.0 中何时/如何引发异常。我寻找解决方案的时间比我愿意承认的要长。最终,我想要实现的目标是“处理”未处理的异常。当抛出异常时,我希望能够捕获有关异常的感兴趣信息,并将其通过电子邮件发送给相应的站点管理员。我通过在我的一个支持 bean 的构造函数中抛出一个 new FacesException() 来强制错误。我在 JSF 1.1 中使用 MyFaces 实现的效果很好。我能够通过包装默认生命周期并简单地覆盖 execute() 和 render() 方法来实现这一点。我按照 Hanspeter 的这篇很棒的帖子进行操作:
“http://insights2jsf.wordpress.com/2009/07/20/using-a-custom-lifecycle-implementation-to-handle-exceptions-in-jsf-1-2/#comment-103”
我现在正在使用 Mojarra 将站点升级到 JSF 2.0。但是,只要在 execute() 方法中抛出/捕获异常,事情仍然很好;在我进入 render() 的那一刻,HttpServletResponse.isCommitted() 等于 true,并且阶段是 PhaseId RENDER_RESPONSE,这当然意味着我不能执行重定向或转发。我不明白 JSF 1.1 和 2.0 在何时/如何提交响应方面发生了什么变化。正如我所指出的,我在 1.1 框架中完美地工作。 经过大量搜索,我发现 JSF 2.0 通过自定义 ExceptionHandler 提供了一个很好的异常处理选项。我关注了 Ed Burns 的博客,在 JSF2 中优雅地处理 ViewExpiredException:
“http://weblogs.java.net/blog/edburns/archive/2009/09/03/dealing-gracefully-viewexpiredexception-jsf2”
正如 Ed 所指出的,通过定义标签和异常/服务器错误代码的类型以及想要将错误发送到哪个页面,总是有 web.xml 方式。只要我发现 404 错误,这种方法就很有效。然而,需要注意的一件有趣的事情是,如果我通过输入像 /myApp/9er 这样的非现有 URL 来强制出现 404 错误,错误处理程序就会很好地工作,但是只要我添加“.xhtml”扩展名(即 /myApp/ 9er.xhtml) 然后 web.xml 定义不处理它。
我注意到 Ed 正在做的一件我没有尝试过的事情是,他没有尝试执行 HttpServletRespone.sendRedirect(),而是利用 Navigationhandler.handleNavigation() 将用户转发到自定义错误页面。不幸的是,这种方法与 Faclets 默认对错误所做的没有什么不同。当然,由于与上述相同的问题,我无法执行 HttpServletResponse.sendRedirect() ; response.isCommitted() 等于 true。
我知道这篇文章会越来越长,所以我将简要说明一下尝试将 PhaseListener 用于相同目的。我使用以下帖子作为指南,但这条路线仍然不成功:
“http://ovaraksin.blogspot.com/2010/10/global-handling-of-all-unchecked.html”“http://ovaraksin.blogspot.com/2010/10/jsf-ajax-redirect -after-session-timeout.html"
所有我都遇到了前面提到的问题。抛出此异常时,响应已处于提交阶段,我无法将用户重定向/转发到标准错误页面。
对于这么长的帖子,我深表歉意,我只是想提供尽可能多的信息以帮助消除歧义。任何人都有任何解决方法的想法/想法,我很好奇 JSF 1.1 和 2.0 之间可能有什么不同,这会导致在我进入生命周期的 render() 阶段后立即提交响应。
非常感谢您对此的任何帮助!!!
【问题讨论】: