Кросс-полевая проверка бобов - почему вы не работаете
У меня есть небольшая проблема с моим заявлением. Я хотел бы проверить, совпадают ли поля пароля и подтверждения пароля вместе, поэтому я попытался сделать это, как в первом ответе на этот вопрос: проверка перекрестных полей с помощью 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>
1 ответ
Ограничения на уровне класса не запускаются автоматически 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;
}
...
}