Java Enterprise Edition (JEE)バージョン 6 シリーズにおいて、これまで RESTful Web Services (JAX-RS)用のJava API 、 Contexts and Dependency Injection (CDI), the Web Tier (Servlet 3, JSF 2)そして EJB 3.1を見てきた。この結びのパートでは、JavaEE 6リリースのコア・フィーチャのひとつである、 Bean Validation (JSR 303)を考察する。 これは、エンティティ バリデーションのためのメタデータモデルとAPIを定義している。バリデーション用のデフォルトのメタデータ ソースは、アノテーションであるが、開発者は、XMLディスクリプタを使用して、メタデータを拡張できる。Validation API は、特定のアプリケーション層やプログラミングモデルとは、結びついていないので、同じセットのバリデーションは、アプリケーションのすべての層によって共有できる。Validation API は、拡張することで、カスタムなバリデーション制約を加えたり、また制約メタデータのリポジトリにクエリする方法を加えたりするメカニズムを提供する。
JEE6の Bean Validationフィーチャができるまでは、開発者は、プレゼンテーションフレームワークで、それからビジネス層で、また永続化層でもバリデーションルールを書かなければならなかった。そしてそれらすべてを同期させなければならなかった。これは、時間もかかるし、間違いを起こしやすかった。Bean Validationモデルは、フィールド、メソッド、あるいは Backing BeanのようなJavaBeanコンポーネントのクラスに書けるアノテーション形式の制約によってサポートされている。制約は、ビルトインのアノテーション( javax.validation.constraints から入手できる) あるいは、ユーザ定義のものでもよい。 ビルトインのアノテーションの内、一般的に使われるいくつかを以下に示す:
- Min: @Minでアノテートされた要素は、特定した最小値以上の値を持つ数でなければならない。
- Max: The @Maxアノテーションは、アノテートされた要素が、特定した最大値以下の値を持つ数であることを検証する。
- Size: @Size は、 アノテートされた要素が特定した最小と最大の間にあることを確認する。サイズバリデーションがサポートされているタイプは、 String, Collection(コレクションのサイズが評価される)、Map, とArrayである。
- NotNull: @NotNull アノテーションは、 アノテートされた要素がnullでないことを確認する。
- Null: @Null でアノテートされた要素は、nullでなければならない。
- Pattern: この アノテーション は、アノテートされた要素(String) が特定のJavaの正規表現とマッチすることを検証する。
ここに示すのは、Java EE 6の Articleに載ったサンプルで、 Bean Validationのアノテーションによって制約を宣言している:
public class Address { @NotNull @Size(max=30) private String addressline1; @Size(max=30) private String addressline2; public String getAddressline1() { return addressline1; } public void setAddressline1(String addressline1) { this.addressline1 = addressline1; } }
@NotNullアノテーションは、アノテートされた要素、addressline1がnullでないことを明記し、@Size アノテーションは、アノテートされた要素、 addressline1とaddressline2が特定した最大値30文字より長くないことを明記する。
Address オブジェクトが、検証される時は、addressline1 の値が、 @NotNull 制約のために定義されたバリデータクラスに渡され、同時に、@Size 制約用に定義されたバリデータクラスにも渡される。関連するバリデータクラスがバリデーションを実行する。ZipCode と名づけられたカスタムな制約の例が次である:
@Size(min=5, max=5) @ConstraintValidator(ZipcodeValidator.class) @Documented @Target({ANNOTATION_TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface ZipCode { String message() default "Wrong zipcode"; String[] groups() default {}; }
他の制約と全く同じように、クラス、フィールドあるいは、プロパティに@ZipCode制約を指定できる。
public class Address { @ZipCode private String zipCode; public String getZipCode() { return zipCode; } public void setZipCode(String zipCode) { this.zipCode = zipCode; } }
Validation API:
Validation API は、プログラム的に、いかに JavaBeanを検証するかを記述する。Bean Validation API 用のデフォルトのpackage は、 javax.validationである。このAPIライブラリにあるクラスのいくつかを以下にリストする:
ConstraintValidator: これは、 interface で、制約バリデーションの実装によりimplementsされる。これは、あるオブジェクトタイプに対する、ある制約を検証するロジックを定義する。
Validator: Validator interface は、オブジェクトグラフを検証する契約を持っている。この interfaceは、スレッドセーフでなければならない。
ConstraintViolation: あるbean に対する制約の違反は、 ConstraintViolation interfaceを使って記述され、違反を記述するメッセージといっしょに、制約違反のコンテキストを知らせる。
ValidationException: バリデーション中に回復不能な障害が起きた場合、 ValidationException が起きる。この例外は、ある状況(無効なグループの定義、無効な制約の定義、無効な制約の宣言)に特化することができる。
制約メタデータを要求するためのAPI:
Bean Validationの仕様では、制約リポジトリにクエリすることができる。このAPIを使って、ツール作成をサポートするばかりでなく、他のフレームワークやライブラリそしてJSRと統合することが期待できる。 Bean Validationの仕様は、バリデーション用のエンジンとオブジェクトの制約に使用するメタデータのリポジトリの両方を提供することを目的にしている。制約の定義、バリデーションそしてメタデータが必要なフレームワーク(Java EE あるいはJava SE) は、これらのサービスを利用するのに、 Bean Validationの仕様に任せることができ、アプリケーションやインフラの見地から不要な重複した作業を避けることができる。
The Bean Validation は、 JSF 2.0 と JPA 2.0 バージョンに統合されている。JSFでは、フォーム入力をあなたのドメインモデルのプロパティにバインドしている。 JSF 2 と Bean Validationは、あなたがバインドしているのが、どのプロパティであるかがわかり、それと関連している制約を実行して、ユーザに制約の違反を知らせる。
Hibernate Validator 4 は、 Bean Validation仕様のリファレンス実装のフレームワークである。 Hibernate Validatorの最新版は、バリデーションのグルーピング、 JPA2 や JSF2とのネィティブな統合、そして拡張されたアノテーションセットのような 新しいフィーチャ を加えている。