Вопрос по hibernate-validator, validation, managed-bean, jsf-2, bean-validation – Кросс-полевая проверка бобов - почему вы не работаете

0

У меня возникла небольшая проблема с моим заявлением. Я хотел бы проверить, совпадают ли поля пароля и подтверждения пароля вместе, поэтому я попытался сделать это, как в первом ответе на этот вопрос:Межполевая проверка с помощью Hibernate Validator (JSR 303)

Проблема в том, что это на самом деле не работает, и у меня нет идеи, почему. Пожалуйста, помогите мне! Это мой первый пост здесь, поэтому, пожалуйста, не будьте слишком резкими для меня.

Вот моя аннотация:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pl.lodz.p.zsk.ssbd2012.ssbd12.ValidationConstraints;

import java.lang.annotation.*;
import javax.validation.Constraint;
import javax.validation.Payload;

/**
 *
 * @author lukasz
 */
@Documented
@Constraint(validatedBy = FieldMatchValidator.class)
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldMatch {

String message() default "{pl.lodz.p.zsk.ssbd2012.ssbd12.ValidationConstraints.FieldMatch}";

Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};

String first();

String second();
}

Вот мой ValidatorClass:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pl.lodz.p.zsk.ssbd2012.ssbd12.ValidationConstraints;

import java.lang.reflect.InvocationTargetException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import org.apache.commons.beanutils.BeanUtils;

/**
 *
 * @author lukasz
 */
public class FieldMatchValidator implements ConstraintValidator<FieldMatch, Object> {

    private String firstFieldName;
    private String secondFieldName;

    @Override
    public void initialize(FieldMatch constraintAnnotation) {
        firstFieldName = constraintAnnotation.first();
        secondFieldName = constraintAnnotation.second();
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext context) {
        try {
            String sFirstField = BeanUtils.getProperty(value, firstFieldName);
            String sSecondField = BeanUtils.getProperty(value, secondFieldName);
            if(sFirstField.equals(sSecondField)){
                return true;
            }
        } catch (IllegalAccessException ex) {
            Logger.getLogger(FieldMatchValidator.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
        Logger.getLogger(FieldMatchValidator.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NoSuchMethodException ex) {
        Logger.getLogger(FieldMatchValidator.class.getName()).log(Level.SEVERE, null, ex);
        }
        return false;
    }
}

А вот и мой боб:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pl.lodz.p.zsk.ssbd2012.ssbd12.Beans;

import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import pl.lodz.p.zsk.ssbd2012.ssbd12.ValidationConstraints.CheckEmail;
import pl.lodz.p.zsk.ssbd2012.ssbd12.ValidationConstraints.FieldMatch;
import pl.lodz.p.zsk.ssbd2012.ssbd12.entities.Account;
import pl.lodz.p.zsk.ssbd2012.ssbd12.mok.endpoint.MokEndpointLocal;

/**
 *
 * @author krzys
 * @author lukasz
 */

@ManagedBean
@RequestScoped
@FieldMatch(first = "password", second = "password2", message = "{pl.lodz.p.zsk.ssbd2012.ssbd12.ValidationConstraints.FieldMatch}")
public class RegisterBean {

    /**
     * Creates a new instance of RegisterBean
     */

    @EJB
    MokEndpointLocal endpoint;

    @Size(min = 3, max = 16, message = "{pl.lodz.p.zsk.ssbd2012.ssbd12.Beans.RegisterBean.login.size}")
    @Pattern(regexp = "[a-zA-Z0-9]+", message = "{pl.lodz.p.zsk.ssbd2012.ssbd12.Beans.RegisterBean.login.invalid}")
    private String login;

    @Size(min = 6, max = 64, message = "{pl.lodz.p.zsk.ssbd2012.ssbd12.Beans.RegisterBean.password.size}")
    @Pattern(regexp = "[a-zA-Z0-9]+", message = "{pl.lodz.p.zsk.ssbd2012.ssbd12.Beans.RegisterBean.password.invalid}")
    private String password;

    private String password2;

    @Pattern(regexp = "[A-Ż][a-ż]+", message = "{pl.lodz.p.zsk.ssbd2012.ssbd12.Beans.RegisterBean.name.invalid}")
    private String name;

    @Pattern(regexp = "[A-Ż][a-ż]+", message = "{pl.lodz.p.zsk.ssbd2012.ssbd12.Beans.RegisterBean.surname.invalid}")
    private String surname;

    @CheckEmail
    private String email = "";


    /**
     * @return the login
     */
    public String getLogin() {
        return login;
    }

    /**
     * @param login the login to set
     */
    public void setLogin(String login) {
        this.login = login;
    }

    /**
     * @return the password
     */
    public String getPassword() {
        return password;
    }

    /**
     * @param password the password to set
     */
    public void setPassword(String password) {
        this.password = password;
    }

    public String getPassword2() {
        return password2;
    }

    public void setPassword2(String password2) {
        this.password2 = password2;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String register ()
    {
//       Account account = new Account();
//       account.setLogin(login);
//       account.setHaslo(password);
//       account.setImie(name);
//       account.setNazwisko(surname);
//       account.setEmail(email);
//       endpoint.register(account);
       return "registerSucces";
    }

    /**
     * @return the surname
     */
    public String getSurname() {
        return surname;
    }

    /**
     * @param surname the surname to set
     */
    public void setSurname(String surname) {
        this.surname = surname;
    }
}

А вот JSF:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core">
<h:head>
    <h:outputStylesheet name="menu.css" library="css" />
    <title>#{messages.registration}</title>
</h:head>

<h:body>
    <ui:composition template="./../resources/mainTemplate.xhtml">

        <h4>#{messages.registration}</h4>
    <ui:define name="content">
        <h4>#{messages.registration}</h4>
        <h1>#{messages.registrationInfo1}</h1>
    #{messages.registrationInfo2}
    <h:form>
        <h2>
            <h:outputText value="#{messages.loginForm}"/>
            <h:inputText id="login" value="#{registerBean.login}" />  
        </h2>
        <h2>
            <h:outputText value="#{messages.passwordForm}" />
            <h:inputSecret id="password" value="#{registerBean.password}" />
        </h2>
        <h2>
            <h:outputText value="#{messages.repeatPasswordForm}"/> 
            <h:inputSecret id="confirm" value="#{registerBean.password2}" />
        </h2>
        <h2>
            <h:outputText value="#{messages.nameForm}"/>
            <h:inputText id="name" value="#{registerBean.name}" />
        </h2>
        <h2>
            <h:outputText value="#{messages.surnameForm}"/>
            <h:inputText id="surname" value="#{registerBean.surname}" />
        </h2>
        <h2>
            <h:outputText value="#{messages.emailForm}"/>
            <h:inputText id="email" value="#{registerBean.email}" />
        </h2>
        <h2>    
            <h:commandButton value="#{messages.send}" action="#{registerBean.register()}" />
        </h2>
    </h:form>
    </ui:define>
    </ui:composition>
</h:body>
</html>
Я не уверен, но я подумал, что аннотации достаточно, потому что другие аннотации, такие как Pattern или CheckEmail (которые я тоже сделал сам) работают нормально. Поправь меня, если я ошибаюсь. AjMeen
В вашем случае, кто должен инициировать проверку? Чтобы запустить проверку на бобе, кто-то должен создатьValidator, вызовvalidate() метод и передать свой объект к нему. Если ваш фреймворк этого не делает, то вам следует сделать это самостоятельно. Slava Semushin

Ваш Ответ

1   ответ
5

Ограничения на уровне класса не запускаются автоматически JSF на этапе проверки. Вы можете использовать только ограничения на уровне полей (более того, JSF оценивает не все поля, а только те, которые находятся в вашем фасете).

Если вы хотите использовать проверку бина, вы можете выполнить проверку вручную:

Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Set<ConstraintViolation<Test>> violations = validator.validate( this, Default.class );

Вы можете сделать это способом регистрации вашего компонента или после фазы обновления модели (но я никогда не пробовал).

В любом случае вы можете использовать проверку JSF вместо проверки bean-компонента или проверить пароли непосредственно в методе регистрации:

public String registration() {
    ...

    if ( !password.equals(password2) ) {
        FacesContext.getCurrentInstance().addMessage( null, new FacesMessage( "Passwords do not match" ) );
        return null;
    }

    ...
}
@ user1591434 Смотрите мое обновление. Имейте в виду, что валидация bean-компонентов - это универсальная система валидации, которая может использоваться везде в java. У JSF есть некоторые средства, которые помогут вам избежать некоторого стандартного кода, например, ручная проверка, которую я предложил вам в моем обновлении. Однако эти средства ограничены валидацией на уровне поля. Если вы хотите проверки на уровне класса, вы должны сделать это вручную, насколько я знаю.
Хорошо, теперь я понимаю, в чем причина, но я все еще не знаю, как решить проблему. Ваш совет слишком широк - я имею в виду, я был бы признателен за пример, потому что теперь я не знаю, что именно я должен делать. Должен ли я сделать некоторые изменения в коде JSF? Вы сказали, что я должен создать класс Validator и вызвать validate () - так что с FieldMatch и FieldMatchValidator? Они больше не нужны? И как мне вызвать метод validate () класса Validator? AjMeen

Похожие вопросы