2011-03-12 56 views
4

在我們的應用中有這樣一個案例:GroupSequence並下令評估JSR 303

  • 的約束應該在特定的順序進行評估。 (便宜至昂貴)
  • 限制不應在違反每個字段後進行評估。
  • 所有字段都應該被驗證。

對於前兩個,groupsequence很適合。但是,對於我的第三個要求,我找不到解決的辦法。

public class AccountBean { 

    @CheepValidation 
    @ExpensiveValidation 
    @VeryExpensiveValidation 
    private String name; 

    @CheepValidation 
    @ExpensiveValidation 
    @VeryExpensiveValidation 
    private String surname 
} 

例如,

假設,對於名稱字段VeryExpensiveValidationconstraint被侵犯和姓字段ExpensiveValidation約束被違反。

對於這種情況我應該顯示:

字段名:只有VeryExpensiveValidation錯誤信息 對於現場的姓:只有ExpensiveValidation錯誤信息

注意,對於現場的姓,我們沒有評估VeryExpensiveValidation約束。

有沒有辦法用JSR 303來實現它?

感謝

回答

3

您可以使用組和@GroupSequence,但它是一個有點笨拙。

public class AccountBean { 

    @CheapValidation(groups=Name1.class) 
    @ExpensiveValidation(groups=Name2.class) 
    @VeryExpensiveValidation(groups=Name3.class) 
    String name; 

    @CheapValidation(groups=Surname1.class) 
    @ExpensiveValidation(groups=Surname2.class) 
    @VeryExpensiveValidation(groups=Surname3.class) 
    String surname; 

    public interface Name1 {} 
    public interface Name2 {} 
    public interface Name3 {} 
    @GroupSequence({Name1.class, Name2.class, Name3.class}) 
    public interface Name {} 

    public interface Surname1 {} 
    public interface Surname2 {} 
    public interface Surname3 {} 
    @GroupSequence({Surname1.class, Surname2.class, Surname3.class}) 
    public interface Surname {} 
} 

然後驗證具有:

validator.validate(myAccountBean, 
    AccountBean.Name.class, AccountBean.Surname.class) 

的關鍵是具有兩個完全獨立的組的序列。

不幸的是,您似乎必須明確列出您要驗證的所有字段的組。我無法使用「默認」@GroupSequence工作。任何人都可以改進呢?

+0

這是驗證AccountBean.Surname後AccountBean.Name以防萬一AccountBean.Name錯誤?我想驗證所有字段。 – Ozgur 2011-04-21 06:13:59

+0

@Ozgur,是的,我測試瞭解決方案,它驗證'姓名'和'姓氏'。傳遞給「驗證」的組列表不會短路;只有@GroupSequence導致短路。 (對?) – 2011-05-06 22:03:26

0

我已經使用GroupSequence實現了有序驗證,但是一般來說,GroupSequence bean驗證實現並不透明。

含義,直到第一組完全驗證,您不能觸發第二組的驗證。

E.g.

我有3個驗證字段與自定義驗證器。這個想法非常簡單:每個字段都應該使用從上到下獨立的驗證器集合(降基數)進行驗證。

 @StringPropertyNotNullOrEmptyConstraint(message = "Group name is required", groups = {ValidationStep1.class})   
     private final StringProperty groupName;  

     @StringPropertyNotNullOrEmptyConstraint(message = "Group password is required", groups = {ValidationStep1.class}) 
     @StringPropertyMatchConstraint(message = "The given password phrases do not match", dependentProperties = {"groupPasswordMatch"}, groups = {ValidationStep2.class}) 
     private final StringProperty groupPassword;  

     @StringPropertyNotNullOrEmptyConstraint(message = "Group password match is required", groups = {ValidationStep1.class}) 
     @StringPropertyMatchConstraint(message = "The given passwords phrases do not match", dependentProperties = {"groupPassword"}, groups = {ValidationStep2.class})  
     private final StringProperty groupPasswordMatch; 


     public interface ValidationStep1 {  
     } 

     public interface ValidationStep2 {  
     } 

     @GroupSequence({GroupDialogModel.class, ValidationStep1.class, ValidationStep2.class}) 
     public interface GroupDialogModelValidationSequence {  
     } 

     ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory(); 
     Validator validator = validatorFactory.getValidator();  

     Set<ConstraintViolation<GroupDialogModel>> constraintViolations = validator.validate(this, GroupDialogModelValidationSequence.class); 

這種方法需要注意的是,每場應該的步驟1成功,轉到步驟2.例如每個驗證後經過ValidationStep1第一和唯一的,即使密碼字段不爲空,但含有不同值,如果組名稱字段不包含任何值,則驗證成功。只有在給組名輸入一些值之後,ValidationStep1組纔會成功,然後顯示ValidationStep2的驗證結果(密碼不匹配)。

在每個序列中爲每個字段做每個組是不好的做法恕我直言,但它似乎沒有其他選擇。

任何其他解決方案,非常感謝。