【问题标题】:Uncaught Exception Handling in JSFJSF 中未捕获的异常处理
【发布时间】:2025-12-26 03:20:23
【问题描述】:

我正在尝试创建一个过滤器来处理异常(请参阅Handling Uncaught Exception in JSF

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
      try {
          log.info("check filter is running");
            chain.doFilter(request, response);
        } catch (Exception e) {
            log.error("Uncaught exception",e);
            request.setAttribute("exception", e);
            request.getRequestDispatcher("/error.xhtml").forward(request, response);
        }
}

我执行如下方法:

    <p:commandButton value="Dispatch Order" update="@form"
        action="#{orderBean.dispatchOrder()}">
    </p:commandButton>

但是,没有处理任何异常。

我在日志中看到错误:

May 21, 2013 6:04:32 PM com.sun.faces.lifecycle.InvokeApplicationPhase execute
WARNING: #{orderBean.dispatchOrder()}: MyException.....

我做错了什么?

【问题讨论】:

    标签: jsf-2 exception-handling


    【解决方案1】:

    那个老问题是针对 JSF 1.x 的,当您发送 JSF 2.x ajax 请求时,答案不适用。仅当您将ajax="false" 添加到&lt;p:commandButton&gt; 或使用标准JSF &lt;h:commandButton&gt; 而不使用&lt;f:ajax&gt; 时才会调用您的过滤器。为了处理 ajax 请求的异常,你需要一个自定义的ExceptionHandler

    另见:

    【讨论】:

    • 我收到了这个错误。 web.xml 或 web-fragment.xml 中需要 HTTP 500 或 java.lang.Throwable 错误页面。都没有找到。我像展示一样为 java.lang.RuntimeException 设置了错误页面。这是预期的吗?
    • 你指的是FullAjaxExceptionHandler?只需在 web.xml 中设置 HTTP 500 或 java.lang.Throwable 错误页面。另见其javadoc
    • 也许在此处添加对 OmniFaces 的引用?
    【解决方案2】:

    这不是 JSF 2.0 中的最佳实践。相反,请参阅:http://javalabor.blogspot.se/2011/09/jsf-2-global-exception-handling.html

    现在您可能会在 cmets 中关注 Solder / Seam 3 背后的一些人推荐 Seam Catch。 Seam Catch 实际上使用了相同的原理,但方式更加精致。当然,这是 CDI 做事的方式,考虑到 JSF2 Beans 的预弃用警告,你应该做 CDI imo。

    Seam Catch 已经移植到 Deltaspike Core,但 JSF 集成并没有在 0.4 中实现,因此您必须自己实现它,然后您可以在 deltaspike 中实现它后替换您的实现。吉拉在这里:https://issues.apache.org/jira/browse/DELTASPIKE-341

    Seam Catch 的源代码将带您走很远https://gist.github.com/mojavelinux/734963。但是您应该像这样获取 BeanManager:

        BeanManager beanManager = BeanManagerProvider.getInstance()
                .getBeanManager();
    
        beanManager.fireEvent(catchEvent);
    

    以下是您需要做的总结:

    1. 去 CDI
    2. 将 Deltaspike Core 添加到类路径
    3. 根据 Seam 的源代码和我发布的修改实现您自己的 ExceptionHandler 等。
    4. 利润!!!现在,您可以使用 Deltaspike 的异常控制以非常流畅的方式捕获未捕获的异常。有关如何实现捕获的详细信息,请参见此处:http://incubator.apache.org/deltaspike/core.html#exception-control

    编辑:BalusC 的建议是一个很好的轻量级候选,它也有这种风格:http://fractalsoft.net/primeext-showcase-mojarra/views/ajaxErrorHandler.jsf

    【讨论】: