Como posso exibir ValidatorException e required = "true" do mesmo campo de entrada em diferentes elementos de mensagens

Eu peguei o seguinteExemplo de kickoff do BalusC e modificou um pouco, adicionando um botão de envio e h: mensagens adicionais e removendo of:ajax deh:inputSecret's (removeu of:ajax porque por algum motivo quando eu deixar o primeiroh:inputSecret ele exibe imediatamente o erro "valor é necessário" para o segundoh:inputSecret - mas o usuário não tem a chance de digitá-lo em ... ??? <- outra pergunta futura? :))

OK, para encurtar a história:

Eu estou tentando descobrir como pode exibir os erros de validação sobre os dois campos de senha (que as senhas não são iguais) no global h: mensagens e não no indivíduo h: mensagem dos campos de senha eu quero que o necessário = "true" será exibido no<h:message de cada campo ...

Mas agora a mensagem de validação (lançada pela minha exceção) e o required = "true" estão sendo exibidos no mesmo lugar

Aqui está o código:

<code><h:outputLabel for="password" value="Password:" />
<h:inputSecret id="password" value="#{bean.password}" required="true">
    <f:validator validatorId="confirmPasswordValidator" />
    <f:attribute name="confirm" value="#{confirmPassword.submittedValue}" />
</h:inputSecret>
<h:message id="m_password" for="password" />

<h:outputLabel for="confirm" value="Password (again):" />
<h:inputSecret id="confirm" binding="#{confirmPassword}" required="true">
</h:inputSecret>
<h:message id="m_confirm" for="confirm" />
</code>

E adicionalh:commandButton comh:messages abaixo desse código:

<code><h:commandButton value="doSomething" action="#{myBean.myAction}">
    <f:ajax execute="password confirm" render="m_password m_confirm"></f:ajax>
</h:commandButton>
<h:messages globalOnly="true" styleClass="validation_value_required"/>
</code>
<code>@FacesValidator("confirmPasswordValidator")
public class ConfirmPasswordValidator implements Validator {

    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        String password = (String) value;
        String confirm = (String) component.getAttributes().get("confirm");

        if (password == null || confirm == null) {
            return; // Just ignore and let required="true" do its job.
        }

        if (!password.equals(confirm)) {
            throw new ValidatorException(new FacesMessage("Passwords are not equal."));
        }
    }

}
</code>

Além disso

Obrigado pela frente

Solução (graças ao BalusC)

mudou

<code><f:attribute name="confirm" value="#{confirmPassword.submittedValue}" />
</code>

para

<code><f:attribute name="confirm" value="#{confirmPassword}" />
</code>

e

<code>String confirm = (String) component.getAttributes().get("confirm");
</code>

para dentro

<code>UIInput confirmPasswordComponent = (UIInput) component.getAttributes().get("confirm");
String confirm = (String) confirmPasswordComponent.getSubmittedValue();
</code>

e

<code>throw new ValidatorException(new FacesMessage("Passwords are not equal."));
</code>

para dentro

<code>context.addMessage(null, new FacesMessage("Passwords are not equal."));
context.validationFailed();
((UIInput) component).setValid(false);
confirmPasswordComponent.setValid(false);
return;
</code>

questionAnswers(1)

yourAnswerToTheQuestion