0

我在這裏有一個小問題與我的應用程序。我想檢查字段密碼和確認密碼匹配在一起,所以我試圖這樣做,就像在這個問題的第一個答案:Cross field validation with Hibernate Validator (JSR 303)跨域bean驗證 - 爲什麼你沒有工作

問題是,它實際上不起作用,我沒有想法爲什麼。請幫幫我!這是我在這裏的第一篇文章,所以請不要對我太苛刻。

這裏是我的註釋:

/* 
* 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> 
+0

在你的情況誰應該引起驗證?爲了在bean上運行驗證,應該創建'Validator',調用'validate()'方法並將對象傳遞給它。如果你的框架沒有這樣做,那麼你應該自己做。 – 2012-08-15 19:15:07

+0

我不確定,但我認爲註釋就夠了,導致像Pattern或CheckEmail(我自己也是這樣)的其他註釋工作得很好。如我錯了請糾正我。 – AjMeen 2012-08-15 20:54:40

回答

4

在驗證階段,JSF不會自動觸發類級約束。您只能使用字段級別的約束(此外,並非所有字段都由JSF進行評估,但僅限於那些位於facelet中的字段)。

如果你想用Bean驗證您可以手動執行驗證:

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

你可以在你的bean的註冊方法或之後更新模型階段(但我從來沒有嘗試過)。

反正你可以使用JSF驗證,而不是Bean驗證或直接檢查密碼的註冊方法:

public String registration() { 
    ... 

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

    ... 
} 
+0

好的,我現在看到了什麼原因,但我仍然不知道如何解決問題。你的建議太廣泛 - 我的意思是我會欣賞一個例子,因爲現在我不知道我該做什麼。我應該對JSF代碼做一些更改嗎?你說我必須創建Validator類並調用validate() - 那麼FieldMatch和FieldMatchValidator的功能是什麼?他們不再需要嗎?我該如何調用Validator類的validate()方法? – AjMeen 2012-08-16 17:01:26

+0

@ user1591434查看我的更新。請記住,bean驗證是一個通用的驗證系統,可以在java中隨處使用。 JSF有一些工具可以幫助您避免一些樣板代碼,例如我在更新中提出的手動驗證。但是,這些設施僅限於實地驗證。據我所知,如果您想要進行課堂級驗證,您必須手動進行。 – Alf 2012-08-16 18:59:52