02.Bean Validation(JSR303)

The standard validation framework (JSR 303: Bean Validation) implemented in Java EE 6.

Java EE 6 標準規範下 Bean 的驗證框架與實作.


發展源由


  1. 在 JEE6 的 Bean Validation 出現之前,開發者不得不在表現層框架、業務邏輯層以及持久層中編寫驗證規則以保證這些撰寫驗證內容是同步性的,但這麼做非常浪費時間而且極易出錯。 
  2. 一個 bean 可能會在 N-tier 應用中多次驗證, 現在不需要到處寫驗證邏輯了. 隨後一個驗證器(validator)會讀取並檢查這些約束。驗證機制可以執行於應用程序中的不同層(表現層、資料存取層),而不必複述任何(前述)這些規則。
  3. 在專案的業務屬性中, 你是不是要經常驗證屬性的取值範圍呢?想要瞭解比較優美的解決方案嗎?用 Annotations 給 class 或者 class 的屬性加上約束(constraint), 在 RT 運行期檢查屬性值是很優雅的.
  4. 註解是一種為領域模型(domain model)指定不變約束的簡潔而幽雅的方法。例如,你能表示一個屬性永遠不為null,一個帳戶餘額一定是正的,等等。這些域模型約束通過為 bean 中的屬性添加註解來加以聲明。
  5. 每個應用程序都有責任確保它們插入到後台資料庫的資料是合法有效的,畢竟,如果這些應用程序所依賴的資料一旦遭到了破壞,那將是災難性的,那應用程序還能 拿什麼來使自己正常運轉呢?比如說,使用正規關係資料庫的一個應用程序,資料庫中的每個欄位都有自己一定的規則和約束,來保證存儲在其中的資料在一定程度上的正確性。任何要使用後台資料庫資料的應用程序都有責任保護它們提交的資料的完整性。
        任何試圖插入或更新不符合標準的資料的操作都有可 能被發現並拒絕。這種檢測可能遍佈在整個應用程序的每個角落,在表現層可能進行一些驗證,在業務邏輯層,商業邏輯對象一般也有商業邏輯的驗證,還有在後台 資料庫也要對資料進行檢查。
        不幸的是,由於這種驗證在應用程序中無處不在,造成了應用程序在一定程度上的驗證資料的代碼冗餘。這並不是應 用程序所希望的,因為這種在多處的重複勞動,使得應用程序的部署和維護要花去更多的時間。如果在整個應用程序中,這些驗證規則可以重複使用,將使得應用程 序更加富有彈性,換句話說就是,部署更快捷,定製更容易,程序更靈活。

    "JSR 303 defines a metadata model and API for JavaBean validation. The default metadata source is annotations, with the ability to override and extend the meta-data through the use of XML validation descriptors. The API is not tied to a specific application tier or programming model. It is specifically not tied to either the web tier or the persistence tier, and is available for both server-side application programming, as well as rich client Swing application developers."


JSR-303


JSR 303 是 JAVA EE 6 中的一項子規範 - Bean Validation,官方參考實作是 Hibernate Validator,此實作與 Hibernate ORM 沒有任何關係。JSR 303 用於對 Java Bean 中的欄位值進行驗證。 

Bean Validation 是通過約束實作的,這些約束以 Annotation 的形式出現,註釋型別可以放在 JavaBean(如 ManagedBean)的屬性、方法或是 Class 上面。  約束既可以是內建的註釋型別(位於 javax.validation.constraints 套件包底下),也可以由使用者自定義。

Bean Validation 已經整合到 JSF 2.0 和 JPA 2.0 中。在 JSF 中可以將表單輸入域值與域值物件的屬性綁定起來。JSF 2 和 Bean Validation 可以判斷出綁定的是哪個屬性並執行與之相關的驗證,還會將約束違背的訊息顯示給使用者。


使用Validator的好處


.使用Validator框架比一般的在應用程序的代碼中定義驗證規則有好多優點,如:
  • .可以在一處為應用程序定義驗證規則;
  • .驗證規則和應用程序是松耦合的;
  • .服務器端和客戶端的驗證規則可以在同一處定義;
  • .配置新驗證規則或修改已有驗證規則變得更加簡單;
  • .支持國際化;
  • .支持正則表達式;
  • .可以用於Web應用程序也可用於標準的Java應用程序;
  • .採用聲明的方法實現而不是編程實現;
除了之 外,Validator最大的特徵就是自身支持可插性(pluggability)。在文章的後
面你將會看到使用Validator框架內置的驗 證規則來更好地完成你的工作,而更重要的是,Validator框架允許你自定義驗證程序,並插入到框架中。


Java EE 6 Bean Validation 提供了實體驗證元資料模型與API 作者 Srini Penchikala


參考實作(RI)


Hibernate Validator 4

http://hibernate.org/subprojects/validator.html

Hibernate Validator 4.x is the reference implementation for JSR 303 - Bean Validation.

JSR 303 defines a metadata model and API for JavaBean validation. The default metadata source is annotations, with the ability to override and extend the meta-data through the use of XML validation descriptors. The API is not tied to a specific application tier or programming model. It is specifically not tied to either the web tier or the persistence tier, and is available for both server-side application programming, as well as rich client Swing application developer.



Bean Validator(JSR-303) 規範的標準實作,此版本包含了許多新特性: (較標準多出許多特性!)
  • 約束組合:自定義的約束,可避免重複代碼,提高可讀性
  • 對群組(Group)的約束:允許你自定義約束,你希望看到的特定子集
  • 類型安全的約束聲明
  • 強大的自定義約束
  • 原生支持JPA2.0和JSF2
  • 增加了類型安全的引導API
  • 對元資料API的支持和XML部署描述符的支持
  • 完全支持JSR-303 Bean校驗器規範

http://code.google.com/p/agimatec-validation/
The goal of the Bean Validation project is to deliver an implementation of the Bean Validation Specfication (JSR303), which is TCK compliant and works on Java SE 5 or later. The initial codebase for the project was donated to the ASF by a SGA from Agimatec GmbH and uses the ASL 2.0 license.





First Example


import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

/**
*
* @author WisdomFish, Kuo
*/
public class Person {

@NotNull
@Min(value = 1)
@Max(value = 9999)
private Long id;
@NotNull
@Size(min = 1, max = 20, message = "姓名的長度必須在{min}和{max}之間!")
private String name;
static ValidatorFactory vf = Validation.buildDefaultValidatorFactory();
static Validator validator = vf.getValidator();

public static void main(String[] args) {
Person s = new Person();
s.name = "123456789012345678901";
Set<ConstraintViolation<Person>> set = validator.validate(s);
for (ConstraintViolation<Person> constraintViolation : set) {
System.out.println(constraintViolation.getMessage());
}
}
}

Running ...
姓名的長度必須在1和20之間!
may not be null




Defining constraints


API, http://java.sun.com/javaee/6/docs/api/javax/validation/constraints/package-summary.html

Constraints can be built-in or user-defined. Several built-in annotations are available in the javax.validation.constraints package. Some of the commonly used built-in annotations are listed below:

  • @Min: The annotated element must be a number whose value must be higher or equal to the specified minimum.

  • @Max: The annotated element must be a number whose value must be lower or equal to the specified maximum.

  • @Size: The annotated element must be between specified minimum and maximum boundaries.

  • @NotNull: The annotated element must not be null.

  • @Null: The annotated element must be null.

  • @Pattern: The annotated element must match the specified Java regular expression.


常用的內建註解列舉如下:
  • Min:被@Min 所註解的元素必須是個數字,其值要大於或等於給定的最小值。
  • Max:被@Max 所註解的元素必須是個數字,其值要小於或等於給定的最大值。
  • Size@Size 表示被註解的元素必須位於給定的最小值和最大值之間。支持Size驗證的資料類型有String、Collection(計算集合的大小)、Map以及陣列數組。
  • NotNull@NotNull 確保被註解的元素不能為null。
  • Null@Null 確保被註解的元素一定為null。
  • Pattern@Pattern 確保被註解的元素(String)一定會匹配(Match)給定的Java正則表達式


http://wiki.redsaga.com/confluence/display/HART/Hibernate+Validator



Custom validation





Validating constraints





Message(s)


@NotNull(message="必要有值!")
@Min(value = 1, message="最小為{value}!")
@Max(value = 5, message="最大為{value}!")
@Size(min=0, max=1, message="最大最小字元為{min}!")
private String name;



Ajax validation for JSF inputs


http://forums.java.net/jive/thread.jspa?messageID=381857
http://stackoverflow.com/questions/2329899/jsf-2-with-hibernate-validator-4-and-tomcat-6


References


  1. Shopping Cart Web Application - Bean Validation
  2. http://sumongh.javaeye.com/blog/98560
  3. Java EE 6 Bean Validation提供了實體驗證元資料模型與API, http://www.infoq.com/cn/news/2010/03/javaee6-validation
  4. Java EE 6核心特徵:Bean Validation解析
  5. 推荐一篇文章 Hibernate Validator

Comments