Jsf 2 将错误消息链接到JSF2中的多个UIComponent

Jsf 2 将错误消息链接到JSF2中的多个UIComponent,jsf-2,validation,facescontext,Jsf 2,Validation,Facescontext,我想问一个关于JSF2的问题。我目前正在混合BalusC在其博客上提出的两段不同的代码: 第一个let以红色突出显示确实有错误消息的字段。 第二种方法是在多个字段上执行验证 我正在寻找一种方法,使FacesContext中的单个错误消息(不希望消息被呈现两次)链接到多个客户端ID(因为由于多字段验证程序,消息确实涉及多个字段) 语言基础是否可能? 如果可以的话,我希望避免使用手工制作的系统(它应该与具有“request”作用域的托管bean一起工作,验证器将确实有错误的clientid放入P

我想问一个关于JSF2的问题。我目前正在混合BalusC在其博客上提出的两段不同的代码:

第一个let以红色突出显示确实有错误消息的字段。 第二种方法是在多个字段上执行验证

我正在寻找一种方法,使FacesContext中的单个错误消息(不希望消息被呈现两次)链接到多个客户端ID(因为由于多字段验证程序,消息确实涉及多个字段)

语言基础是否可能? 如果可以的话,我希望避免使用手工制作的系统(它应该与具有“request”作用域的托管bean一起工作,验证器将确实有错误的clientid放入PhaseListener访问的列表中)


提前谢谢你的提示。在FacesContext上看不到任何接近addMessage()的东西可以完成这项工作,但可能有一种方法…

如果消息出现两次,则意味着两个组件都启动了相同的验证程序,或者启动了一次验证程序,但隐式地将消息添加到另一个组件

我知道您希望将这两个组件标记为无效(以便突出显示),并且只需要一条消息。在这种情况下,您需要确保验证程序启动一次,并且另一个组件正在检索空/空消息

您只需要更改验证器以检索整个组件作为属性而不是它的值(注意:我同时也相应地编辑了这篇旧文章;它还有另一个好处),并且您需要更改阶段侦听器以删除空/空消息

例如,鉴于:

<h:outputLabel for="password" value="Password" />
<h:inputSecret id="password" value="#{bean.password}" required="true">
    <f:validator validatorId="passwordValidator" />
    <f:attribute name="confirm" value="#{confirm}" />
</h:inputSecret>
<h:message for="password" styleClass="error" />

<h:outputLabel for="confirm" value="Confirm password" />
<h:inputSecret id="confirm" binding="#{confirm}" required="true" />
<h:message for="confirm" styleClass="error" />
在侦听器阶段:

Iterator<String> clientIdsWithMessages = facesContext.getClientIdsWithMessages();

while (clientIdsWithMessages.hasNext()) {
    String clientIdWithMessages = clientIdsWithMessages.next();

    if (focus == null) {
        focus = clientIdWithMessages;
    }

    highlight.append(clientIdWithMessages);

    if (clientIdsWithMessages.hasNext()) {
        highlight.append(",");
    }

    Iterator<FacesMessage> messages = facesContext.getMessages(clientIdWithMessages);

    while (messages.hasNext()) {
        if (messages.next().getSummary() == null) {
            messages.remove(); // Remove empty messages.
        }
    }
}
Iterator<String> clientIdsWithMessages = facesContext.getClientIdsWithMessages();

while (clientIdsWithMessages.hasNext()) {
    String clientIdWithMessages = clientIdsWithMessages.next();

    if (focus == null) {
        focus = clientIdWithMessages;
    }

    highlight.append(clientIdWithMessages);

    if (clientIdsWithMessages.hasNext()) {
        highlight.append(",");
    }

    Iterator<FacesMessage> messages = facesContext.getMessages(clientIdWithMessages);

    while (messages.hasNext()) {
        if (messages.next().getSummary() == null) {
            messages.remove(); // Remove empty messages.
        }
    }
}
<h:inputText styleClass="#{component.valid ? '' : 'error'}" />