1. モデルの中(データベーススキーマの制約が典型的)
2. アプリケーションコードの中
これらはどちらも重要である。データベースでの制約は、アプリケーションコードの移行が必要とされる際に、データモデルの再利用を可能にする。アプリケーションレベルのバリデーションは、モデルレベルの制約を使って手軽に実現できるものよりもきめ細かなコントロール(「これは有効な E メールアドレスか?」「顧客の誕生日が未来の日付になっていないか?」など)が可能だし、アプリケーションのユーザに意味のあるエラーメッセージを返すのもずっと簡単だ。アプリケーションレベルのバリデーションはその性質上、複数個所に記述され、アプリケーションのさまざまな層にわたって作業の重複が発生する可能性がある。たとえば、典型的な WEB アプリケーションでは、フィールドレベルのバリデーションを行うためにブラウザ上で JavaScript が実行され、サーバサイドではより複雑なビジネスルールにもとづくバリデーションが行われる。バリデーションの定義を一箇所に集中させ、さまざまなレイヤでその定義を共有することができれば、非常に望ましい。
Hibernate Validator のリード開発者である Emmanuel Bernard 氏が主導する JSR-303 は、Java EE 6 のための制約メタデータモデルの標準化を目指している。現在、仕様のアーリードラフト(source)がリリースされ、エキスパートグループがフィードバックを求めている。フィードバック収集の一環としてフォーラム(source)発足しており、また Bernard 氏は、Hibernate ブログに連載記事(パート 1(source)、パート 2 (source))を投稿しはじめ、API がどのように動作するのかを記述している。
JSR-303 は、その誕生のいきさつを考えれば当然だが、JBoss の Hibernate Validation に多大な影響を受けている。そのほかのいくつかのバリデーション用フレームワーク(たとえば Xwork や Apache Commons Validator など)にも影響を受けてはいるが。この仕様では、ほとんどのケースでアノテーションを利用し、実行時のバリデーションとメタデータ取得のための標準 API を提供する。制約アノテーションはそれぞれ String 型のメッセージを定義しなくてはならない。これはエラーメッセージとして利用される。エラーメッセージは国際化に対応している。制約はオブジェクトのフィールド、getter メソッド、クラス、スーパークラス、インタフェースに宣言することができ、オブジェクトの検証を実行すると、それらすべての制約が検証される。たとえば次のコードは street1 という名前の String オブジェクトを作成し、それに長さが最大 50 文字で入力を必須とする制約をつける。
@NotEmpty @Max(50)
private String street1;
フレームワークは拡張できるように設計されているので、アプリケーションに専用の制約を追加定義できる。Bernard 氏の最初のブログエントリ(source)によると制約の定義に必要なものは次のとおりである。
「制約は次の項目から構成される。
• アノテーション
• 制約バリデーションの実装アノテーションはドメインモデル上で制約を表わすために用いられるのに対し、バリデーションの実装は入力された値が制約をクリアするかどうかを決定する。」
仕様では、インスタンスのバリデーションと同様にオブジェクトグラフのバリデーションもサポートされる。そのため、たとえば仮に ClientDetails という Bean が Address という Bean を @valid アノテーション付きのフィールドに保持していたら、バリデータは ClientDetails Bean の検証時に Address Bean の内容も検証する。.
この仕様と Hibernate Validator との間にはひとつ重大な違いがある。それは、バリデーションのサブセットを作成する方法を提供する、グループの概念である。ある制約のセットがエラーなしでクリアされなければ次のセットが実行されないようにするために、グループは順序をもつ( @GroupSequence アノテーションを使って設定する)。グループは JavaBean の部分的なバリデーションも可能にする。ドラフト仕様はこれが役に立つ 2 つのシナリオを提示している。
「• 2 番目のグループが適切に実行されるために安定した状態が求められる場合Java EE 6 における技術のさまざまなところで JSR-303 が役に立つはずである。たとえば ORM ツールによって生成された際の DDL の更新や、Java Persistence API による挿入・更新時のエンティティのバリデーション、あたらしい WebBeans API、そして JavaServerFaces コンポーネントなど。いずれも疑う余地のない候補のように思える。
• 2 番目のグループが時間や CPU やメモリを激しく消費するため、可能であれば実行を避けたい場合」
原文はこちらです:http://www.infoq.com/news/2008/04/303-validation-draft