JSF 2.0 - 2-й валидатор вызван, хотя 1-й валидатор не работает

Я использую MyFaces 2.0.4 и CDI WAS 8.0.0.5 (не могу заменить версию JSF 2.0 WAS 8 без потери CDI).

У меня есть 2 пользовательских валидатора, зарегистрированных для компонента. Первый делает сравнение нескольких полей. Второй валидатор использует CDI для внедрения SSB, который использует диспетчер сущностей для вызова базы данных.

Если я введу информацию, из-за которой 1-й валидатор намеренно потерпел неудачу, 2-й валидатор все еще выполняется Зачем? Как я могу избежать 2-й проверки, если первая проверка не пройдена? Я думал, что если один валидатор потерпел неудачу, то все последующие валидации будут обойдены.

<h:form id="registrationForm">
    <fieldset>
        <p:messages id="messages" showDetail="true" autoUpdate="true" closable="true" />
        <legend>Register</legend>
        <div class="form-row">
            <h:outputLabel for="userId" value="*User Id"/>
            <h:inputText id="userId" value="#{registration.userId}" required="true" size="20">
                <f:validator validatorId="userIdPasswordValidator" />
                <f:attribute name="passwordComponent" value="#{passwordComponent}"/>
                <f:validator binding="#{duplicateUserValidator}" /> <-- uses CDI
            </h:inputText>
        </div>
        <div class="form-row">
            <h:outputLabel for="password" value="*Password"/>
            <h:inputSecret id="password" type="password" binding="#{passwordComponent}" value="#{registration.password}" required="true">
            </h:inputSecret>
        </div>
        <div class="form-row">
            <h:outputLabel for="confirmPassword" value="*Confirm Password"/>
            <h:inputSecret id="confirmPassword" type="password" value="#{registration.confirmPassword}" required="true" />
        </div>
        <div class="form-row">
            <h:commandButton styleClass="btn btn-warning" value="Register" type="submit" action="#{registration.register}" />
        </div>
    </fieldset>
</h:form>

1-й валидатор:

@FacesValidator("userIdPasswordValidator")
public class UserIdPasswordValidator implements Validator {

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

        if (userId.equals(password)) {
            FacesMessage message = new FacesMessage(null, "The Password cannot be the same as your User ID.");
            throw new ValidatorException(message);
        }
    }
}

2-й валидатор:

@Named
@RequestScoped
public class DuplicateUserValidator implements Validator {

@Inject
UserService userService;

    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {

    if (userService.getUser(value.toString()) != null) {
        FacesMessage message = new FacesMessage(null, "This User ID is already registered. Please logon or choose another one to register.");
        throw new ValidatorException(message);
    }
}

}

1 ответ

Решение

Чтобы достичь желаемого результата, вам следует позвонить renderResponse() как указано в следующей выдержке из оракула:

Если какие-либо методы проверки или прослушиватели событий вызвали renderResponse в текущем FacesContext, реализация JavaServer Faces переходит к фазе ответа рендеринга.


Боюсь, что именно так работает этап валидации. Из оракула:

На этом этапе реализация JavaServer Faces обрабатывает все валидаторы, зарегистрированные в компонентах дерева. Он проверяет атрибуты компонента, которые определяют правила проверки, и сравнивает эти правила с локальным значением, сохраненным для компонента.

Если локальное значение недопустимо, реализация JavaServer Faces добавляет сообщение об ошибке в экземпляр FacesContext

Ключевыми фразами здесь являются процессы, которые проверяют все валидаторы, и добавляет сообщение об ошибке в экземпляр FacesContext. Хотя здесь не очень ясно, что это означает, что этап проверки в целом будет завершен, а сообщения поставлены в очередь. После завершения он переходит к соответствующей фазе.

Другие вопросы по тегам