【问题标题】:How shall technical exceptions be handled when invoked through a listener通过监听器调用的技术异常如何处理
【发布时间】:2014-02-03 22:50:56
【问题描述】:

我正在使用带有 valueChangeListener 属性的<h:selectOneMenu>。侦听器调用一些业务代码(例如数据库查询)以根据新选择的值加载附加数据。我注意到,当该代码中发生(意外)异常时,AbortProcessingException 会包装原始异常,然后是日志,但不会通知用户出现问题。

有没有办法通知用户在调用侦听器时出现意外的致命错误?

我从Differences between action and actionListener 知道一个动作更适合这样的表达式,但是我不能在<h:selectOneMenu> 中设置一个动作,而只能设置一个监听器。我应该如何更改我的页面,以便在所选项目更改时调用“真正的业务操作”(允许失败的操作)?

【问题讨论】:

    标签: jsf jsf-2


    【解决方案1】:

    JSF 有 FacesMessages 的概念。这些是在<h:messages /> 标签的帮助下呈现的。经常做的是捕捉任何异常并将javax.faces.application.FacesMessage 添加到 FacesContext 中,为用户提供他需要的信息(另请参阅"catch exception in managed bean and show message on screen in jsf2")。

    FacesContext.getCurrentInstance().addMessage(
        null, 
        new FacesMessage(Severity.INFO, <see details for possible fills>)
    );
    

    还有办法引入自己的ExceptionHandlerFactory——就像文章中提到的"Global handling of all unchecked / unexpected exceptions in JSF 2"——你检查过这种可能性吗? (另见this answer/comment to BalcusCs article

    作为可能性二,你可以例如在 selectOneMenu 更改后使用 ajax-request 并触发另一个监听器(它稍后执行 ValueChangedListener 并提供 AjaxBehaviorEvent 作为参数,我发现在 BL 方面更有帮助)。这是一些元代码...

    <h:selectOneMenu ...>
      <f:selectItems ... />
      <f:ajax render="..." execute="..." listener="..." />
    </h:selectOneMenu>
    

    希望对你有帮助...

    【讨论】:

    • 我不想将每个侦听器都包含在 try {...} catch (Exception) {addMessage("error");} 中。我希望与普通操作相同的行为:任何致命/意外异常仅由网络服务器捕获并显示错误页面。
    • 此外,解决方案 2 仍然调用侦听器,JSF 将吞下侦听器引发的任何异常。
    • 总是乐于帮助您实现目标。没错,侦听器通常会吞下异常,因此解决方案 1 可帮助您捕获它并通过 FacesMessages 向用户发送一条单独的消息。如果您想要“一刀切”的解决方案,请调查ExceptionHandlerFactory 解决方案。您也是对的, f:ajax-listener 是“只是另一个侦听器”,但是由于它是在生命周期的其他部分执行的,因此它可能会为您提供其他可能性,例如转发/重定向。这是你的项目,你的决定。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多