【问题标题】:How to remove FacesMessages from the FacesContext?如何从 FacesContext 中删除 FacesMessages?
【发布时间】:2011-02-24 12:53:01
【问题描述】:

在我的屏幕上,我有一个下拉菜单(选择框),在选择该下拉菜单中的任何选项时,我使用 javascript/css 在选择框旁边显示一个或多个文本框 - display:none 和 display :堵塞。所有这些输入控件都采用相同的 jsf 格式。每个输入控件都有自己的验证器。问题是假设用户从选择框中选择 option1 并且没有为 inputbox1 输入值或输入错误值,我在验证器中添加自定义 FacesMessage 并显示适当地假设用户第二次选择 option2 并为 inputbox2 输入错误的值,然后在验证器中添加另一个 FacesMessage。但是现在两个消息都显示了 - 意味着 - inputbox1 和 inputbox2 的消息 - 这是错误的 我的假设是,发生这种情况是因为它们以相同的形式存在并且它们的实例尚未在FacesContext 和 UIView 中。我决定以这种方式删除消息

Iterator<FacesMessage> msgIterator = FacesContext.getCurrentInstance().getMessages();
    while(msgIterator.hasNext())
    {
        msgIterator.next();
        msgIterator.remove();
    }

但这有时会给出 java.util.NoSuchElementException org.apache.myfaces.shared_impl.renderkit.html.HtmlMessagesRendererBase$MessagesIterator.next

所以 2 个问题:

1) 以这种方式删除 FacesMessage 有什么问题?我正在使用 myfaces-api-1.2.3.jar 和 myfaces-impl-1.2.3.jar

2) 是否有更好的方法来处理我的场景?我只想在每次处理 jsf 请求时显示相关消息

谢谢

【问题讨论】:

    标签: jsf


    【解决方案1】:

    我不使用 MyFaces,所以我不能详细说明这一点,但在 Sun RI (Mojarra) 中,大约 1.5 年前的 1.2_07 版本中修复了不可移除的人脸消息的错误。

    因此,要实现您想要的,请尝试将 MyFaces 升级到可用的最新版本(他们可能也修复了相同的错误)或替换为 Mojarra

    【讨论】:

    • 感谢您的回答。问题不在于我无法从 FacesContext 中删除消息。问题是每次提交表单时,很少有输入控件(未使用 display:none 显示)保留了一些值(),因此验证器和支持 Bean 代码为那些不可见的输入控件添加了 FacesMessages FacesContext。现在,每次更改选择选项时,我都会清除其他不必要的表单字段,因此不会添加消息。我说的对吗?
    【解决方案2】:

    问题不在于我无法从 FacesContext 中删除消息。问题是每次提交表单时,很少有输入控件(未使用 display:none 显示)保留了一些值(),因此验证器和支持 Bean 代码为那些不可见的输入控件添加了 FacesMessages FacesContext。现在,每次更改选择选项时,我都会清除其他不必要的表单字段,因此不会添加消息。

    【讨论】:

      【解决方案3】:

      据我所知,这还不够,因为在

      org.apache.myfaces.context.servlet.FacesContextImpl
      

      (版本:2.0.15,修订:1364593),有 2 个消息列表(_orderedMessages_messages),您的方法仅清除 _orderedMessages

      要清除_messages,请执行以下操作:

      Iterator<String> itIds = FacesContext.getCurrentInstance().getClientIdsWithMessages();
      while (itIds.hasNext()) {
          List<FacesMessage> messageList = FacesContext.getCurrentInstance().getMessageList(itIds.next());
          if (!messageList.isEmpty()) { // if empty, it will be unmodifiable and throw UnsupportedOperationException...
              messageList.clear();
          }
      }
      

      还请注意,这是非常脆弱的,因为它依赖于实现细节,但我找不到更好的方法:(

      【讨论】:

      • 在 JSF2.0 (Mojarra) 中,即使列表不为空,它也会抛出 UnsupportedOperationException
      【解决方案4】:
      FacesContext context = FacesContext.getCurrentInstance();
      Iterator<FacesMessage> it = context.getMessages();
      while ( it.hasNext() ) {
          it.next();
          it.remove();
      }
      

      【讨论】:

        【解决方案5】:
        if (FacesContext.getCurrentInstance().getMessages() != null) {
                FacesContext.getCurrentInstance().getMessages().remove();
            }
        

        【讨论】:

        • 这会导致 JSF1073: javax.faces.event.AbortProcessingException 在处理 INVOKE_APPLICATION 期间捕获
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-10-26
        • 2013-06-22
        • 2021-12-26
        • 2011-02-24
        • 1970-01-01
        • 1970-01-01
        • 2011-02-15
        相关资源
        最近更新 更多