【问题标题】:How to swallow an exception in JSF 1.2/Mojarra如何在 JSF 1.2/Mojarra 中吞下异常
【发布时间】:2011-12-26 07:11:56
【问题描述】:

ViewExpiredException 正在通过重定向到登录屏幕进行处理。问题是异常仍然被记录,客户强烈希望server.log 没有异常。

虽然在这种情况下这可能是一个有问题的要求,但我仍然必须实现它。我们使用 Mojarra 并在 JBoss EAP 5.1 上部署

MyFaces approach 没有帮助,因为我显然无法使用 Mojarra 包装 MyFacesServlet

我无法应用 JBoss JSF guide 中给出的建议来包装 Faces servlet,因为我在任何地方都找不到 jsf-integration-deployer-jboss-beans.xml

我也无法让approach proposed by Ed Burns 工作。我猜原因是它针对 JSF2,因为我在我的 jar 中找不到 javax.faces.context.ExceptionHandlerFactory

更糟糕的是,我对 JSF 还很陌生,所以我不得不依赖详细的指导,在寻找这些指导时我找到了上述方法但未能应用它们。

谢谢

【问题讨论】:

  • 有什么理由不能在 log4j 配置中使用过滤器或阻止某些记录器来处理它?
  • @mrembisz 不是真的。争取 JSF-y 解决方案,我只是还没有想到这一点。我会解决的。谢谢

标签: java jsf jakarta-ee jsf-1.2 mojarra


【解决方案1】:

我在 JSF 2.0 中遇到了同样的问题,实现由 IBM Websphere 8.5.5.3 提供。

我尝试使用 ExceptionHandlerWrapper 检查 ViewExpiredException 和 重定向到会话过期页面(或登录页面),但我无法消除以下错误,遗憾的是此错误在处理程序之前打印:

StateUtils E View State cannot be reconstructed

但我设法通过实现一个 servlet 过滤器来解决它,该过滤器将检查任何潜在的 ViewExpiredException,如果有的话,它将重定向到会话过期页面。

HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;

HttpSession session = request.getSession(false);

boolean requestContainsViewState = (request.getParameter("javax.faces.ViewState") != null);
boolean potentialViewExpiredException = (session == null && requestContainsViewState);
if (potentialViewExpiredException) {
    // No session found and potential ViewExpiredException, redirect to session expired page.
    response.sendRedirect(request.getContextPath() + "/pages/error/expired.xhtml");
} else {
    chain.doFilter(req, res);
}

编辑:您需要确保这是过滤器链中的第一个过滤器,如果有以前的过滤器并且此过滤器创建了一个会话,则上述解决方案将不适合您。

【讨论】:

    【解决方案2】:

    那篇文章确实是针对 JSF 2.x 的。 JSF 1.x 没有任何异常处理工具。

    只需捕获并重定向你自己,而不是让容器来做。过滤器是一个明智的选择:

    try {
        chain.doFilter(request, response);
    } catch (ServletException e) {
        if (e.getRootCause() instanceof ViewExpiredException) {
            HttpServletRequest req = (HttpServletRequest) request;
            HttpServletResponse res = (HttpServletResponse) response;
            res.sendRedirect(req.getContextPath() + "/errors/session-expired.jsf");
        } else {
            throw e;
        }
    }
    

    web.xml 中将其映射到FacesServlet 的servlet 名称上以使其运行。

    【讨论】:

    • 谢谢,听起来很合理。我找到了关于 servlet 过滤器的教程并立即阅读。将尽快提供反馈
    • 这很简单。上面的代码需要完全进入doFilter() 方法。 init()destroy() 可以留空。您可以在我们的 servlet 过滤器 wiki 中找到一个模板:stackoverflow.com/tags/servlet-filters/info 过滤器映射的唯一区别是您应该使用 <servlet-name>TheServletNameOfYourFacesServlet</servlet-name> 而不是 <url-pattern>
    • 这是一场势均力敌的比赛,它设法摆脱了日志中的堆栈跟踪。但我仍然得到SEVERE [javax.enterprise.resource.webcontainer.jsf.lifecycle] ... Exception thrown during phase execution: javax.faces.event.PhaseEvent。这会在引发异常之前立即记录。
    • 哦,对了,这个。嗯,这真的是记录器配置的食物。详情请看这里:stackoverflow.com/questions/7162134/…
    • 尽管将 logging.properties 放入我的 WEB-INF,但我无法影响 util logging。但是 log4j 配置挽救了这一天。再次感谢。
    猜你喜欢
    • 2013-07-14
    • 2014-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-12
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多