2012-01-06 2115 views
32

使用javax.validation.constraints(如@Size,@NotNull等)的註釋需要什麼樣的配置?這裏是我的代碼:來自javax.validation.constraints的註釋不起作用

import javax.validation.constraints.NotNull; 
import javax.validation.constraints.Size; 

public class Person { 
     @NotNull 
     private String id; 

     @Size(max = 3) 
     private String name; 

     private int age; 

     public Person(String id, String name, int age) { 
     this.id = id; 
     this.name = name; 
     this.age = age; 
     } 
} 

當我嘗試在其他類中使用它,驗證不起作用(即沒有錯誤創建的對象):

Person P = new Person(null, "Richard3", 8229)); 

爲什麼沒有這個應用約束爲idname?我還需要做什麼?

+9

它不能通過魔法工作,你需要配置一個驗證器。這段代碼運行在什麼上下文中? – skaffman 2012-01-06 11:02:25

回答

38

對於JSR-303 Bean驗證在Spring的工作,你需要幾件事情:註解

  1. MVC命名空間配置:<mvc:annotation-driven />
  2. JSR-303規範JAR:validation-api-1.0.0.GA.jar(看起來你已經有了)
  3. 規範的實現,比如Hibernate Valida重刑,這似乎是最常用的例子:hibernate-validator-4.1.0.Final.jar
  4. 在bean進行驗證,驗證的註釋,無論是從規範JAR或從實現JAR(你已經這樣做)
  5. 在處理程序中要驗證,用@Valid註釋要驗證的對象,然後在方法簽名中包含BindingResult以捕獲錯誤。

例子:

@RequestMapping("handler.do") 
public String myHandler(@Valid @ModelAttribute("form") SomeFormBean myForm, BindingResult result, Model model) { 
    if(result.hasErrors()) { 
     ...your error handling... 
    } else { 
     ...your non-error handling.... 
    } 
} 
+0

這爲我們提供了驗證器的默認配置。現在,我想在使用前配置驗證器。我可以在哪裏配置它?任何覆蓋執行或設置調用? – Stephane 2016-01-08 14:01:03

+2

我遇到的問題是我沒有意識到我需要爲每個成員變量添加'@ Valid',這也是一個包含驗證約束的對象。 – WhiteKnight 2016-03-17 09:20:39

+0

謝謝你,先生,你救了我幾個小時的調試。 – Chad 2017-05-25 10:45:46

19

您應該使用驗證器來檢查您的課程是否有效。

Person person = ....; 
ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); 
validator = factory.getValidator(); 
Set<ConstraintViolation<Person>> violations = validator.validate(person); 

然後,迭代違規集合,你可以發現違規。

+0

我認爲,無論使用什麼框架,這個答案都是完美的答案。謝謝..但我有一個疑問,我們如何驗證一個參數傳遞給沒有任何框架的上下文中的某個方法。例如'test(@NotNull String str)',我們可以寫相同的驗證器嗎? – agpt 2014-04-23 12:44:14

5

如果您想要驗證它,您必須在實體上調用Validator on。然後,你將得到一組ConstraintViolationException,其基本上顯示你的實體的哪個字段存在違反約束的條件,以及它究竟是什麼。也許你也可以分享一些你期望驗證你的實體的代碼。

如果在事務中使用多個數據修改,或者在得到驗證異常時執行其他操作,則通常使用的技術是在@PrePersist和回滾事務中進行驗證。

您的代碼應該是這樣的:

@PrePersist 
public void prePersist(SomeEntity someEntity){ 
    Validator validator = Validation.buildDefaultValidatorFactory.getValidator(); 
    Set<ConstraintViolation<SomeEntity>> = validator.validate(someEntity); 
    //do stuff with them, like notify client what was the wrong field, log them, or, if empty, be happy 
} 
-1

我對春天來說還是比較新的,所以請帶上我的答案。當我使用它時,我也無法使@NotNull工作。我有一個輸入字段的屏幕,我沒有填寫它,並向前移動我的屏幕(最終保存到某個數據庫)。

我只是爲了絆倒@NotBlank而絞盡腦汁。無論如何,這是我的回答。有問題的領域是空白的,我想它是「」或每個說一個空字符串不爲空。因此,對@NotBlank的支票被抓住了。

不知道這是否會對您有所幫助,但是如果您也正在努力解決一些@NotNulls未被捕獲的問題,那麼調查這種可能性是不是很痛苦。

1

在我的情況下,我有一個自定義的類級約束沒有被調用。

@CustomValidation // not called 
public class MyClass { 
    @Lob 
    @Column(nullable = false) 
    private String name; 
} 

只要我添加一個字段級約束到我的類,無論是自定義或標準的,類級約束開始工作。

@CustomValidation // now it works. super. 
public class MyClass { 
    @Lob 
    @Column(nullable = false) 
    @NotBlank // adding this made @CustomValidation start working 
    private String name; 
} 

好像錯誤行爲給我,但很容易解決我猜

+0

謝謝!我看到了同樣的行爲。 – Steve 2017-04-06 18:00:09

-1

您需要添加@Valid每個成員變量,這也就是包含驗證對象限制。

0

所以@服務接口的@Valid只適用於該對象。如果你在ServiceRequest對象的層次結構中有更多的驗證,那麼你可能會明確地觸發驗證。所以這就是我如何做到這一點:

public class ServiceRequestValidator { 

     private static Validator validator; 

     @PostConstruct 
     public void init(){ 
     validator = Validation.buildDefaultValidatorFactory().getValidator(); 
     } 

     public static <T> void validate(T t){ 
     Set<ConstraintViolation<T>> errors = validator.validate(t); 
     if(CollectionUtils.isNotEmpty(errors)){ 
      throw new ConstraintViolationException(errors); 
     } 
    } 

} 

如果您想觸發對該對象的驗證,您需要在對象級別具有以下注釋。

@Valid 
@NotNull