2010-10-25 35 views
9

我有一個表單我想要驗證。它包含2個地址變量。地址1一直被驗證,地址2已經根據一些條件來進行驗證Spring MVC和JSR-303休眠條件驗證

public class MyForm { 
    String name; 
    @Valid Address address1; 
    Address address2; 
} 

public class Address { 
    @NotEmpty 
    private String street; 
} 

我控制器自動驗證並綁定自己的狀態OBJ

@RequestMapping(...) 
public ModelAndView edit(
     @ModelAttribute("form") 
     @Valid 
     MyForm form, 
     BindingResult bindingResult, 
     ...) 

     if(someCondition) { 
      VALIDATE form.address2 USING JSR 303 

的問題是,如果我使用LocalValidatorFactoryBean驗證我不能重用Spring提供的BinidingResult對象。綁定不會爲「結果」目標對象的工作是「MyForm的」,而不是「地址」

validate(form.getAddress2(), bindingResult) //won't work 

我想知道什麼是標準/清潔方法進行條件驗證。

我在編程思考在我的控制器中創建一個新的BindingResult。

final BindingResult bindingResultAddress2 = new BeanPropertyBindingResult(address2, "form"); 
validate(form.getAddress2(), bindingResultAddress2); 

但隨後的錯誤列表,我從bindingResultAddress2獲得不能添加到普通「bindingResult」作爲字段名不正確(而不是「address2.street」街')和結合將無法工作。

一些骯髒的方法將擴展BeanPropertyBindingResult接受一些字符串追加到字段名稱..你有更好的方法?

回答

5

用於驗證層次結構的標準方法是使用pushNestedPath()/popNestedPath(),雖然我不知道它是如何發揮與JSR-303:

bindingResult.pushNestedPath("address2"); 
validate(form.getAddress2(), bindingResult); 
bindingResult.popNestedPath(); 
+1

感謝axtavt你應該使用Spring本地驗證API,它的工作原理。我想知道這是否是實現它的最佳方法,爲什麼@Valid中沒有組屬性,並且JSR-303組概念是實現條件驗證的唯一方法 – mickthompson 2010-10-25 15:06:59

+3

有一個針對'@ Valid'組的特性請求:https://jira.springframework.org/browse/SPR-6373 – axtavt 2010-10-25 15:34:12

+0

非常有幫助,謝謝 – mickthompson 2010-10-26 10:29:32

1

我從來沒有嘗試過自己,但我認爲,正確的做法是使用validator groups

+0

不幸的@Valid沒有組 – mickthompson 2010-10-25 15:02:04

+0

這是不幸的 - 看到我上面的評論。我認爲這是規範的一個很好的補充,這種實用性應該比理想主義更受歡迎。 – 2011-02-03 19:59:25

+0

或者爲了安撫理想主義者,我們應該停止調用這個'Bean Validation Framework'並開始將其稱爲'Java驗證框架',並且除了對象圖之外還添加對方法參數和返回值的支持。 – 2011-02-03 20:01:09

0

首先,讓我們來看看@javax.validation.Valid API

馬克協會作爲級聯。關聯的對象將通過級聯進行驗證。

春框架使用@Valid 作爲標記驗證其命令對象,它破壞了目的。 Spring應該創建自己的特定註釋,它指定應該驗證的組。

不幸的是,如果你需要驗證某些羣體

public void doSomething(Command command, Errors errors) { 
    new BeanValidationValidator(SomeUserCase.class, OtherUserCase.class) 
     .validate(command, errors); 

    if(errors.hasErrors()) { 

    } else { 

    } 
} 

BeanValidationValidator可以實現爲

public class BeanValidationValidator implements Validator { 

    javax.validation.Validator validator = ValidatorUtil.getValidator(); 

    private Class [] groups; 

    public BeanValidationValidator(Class... groups) { 
     this.groups = groups; 
    } 

    public void validate(Object command, Errors errors) { 
     Set<ConstraintViolation<Object>> constraintViolationSet = validator.validate(command, groups); 

     for(ConstraintViolation<Object> constraintViolation: constraintViolationSet) { 
      errors.rejectValue(constraintViolation.getPropertyPath().toString(), null, constraintViolation.getMessage()); 
     } 
    } 

} 
+0

我恭敬地不同意將這些組添加到@Valid註釋中會損害其目的。我認爲這是一個增強。 @Valid說「這個對象應該被驗證」。添加組意味着「這個對象應該以這種方式驗證」。沒有理由相同的陳述不能適用於對象圖的級聯關聯以及方法參數。另外,規範應該隨着明顯有價值的增加而發展;將組添加到@Valid將允許許多框架消除重複的代碼。規格應該比實用性更偏向理想主義。 – 2011-02-03 19:57:30