BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ アーティクル インタビュー: Emmanuel Bernard氏にBean Validation仕様について聞く

インタビュー: Emmanuel Bernard氏にBean Validation仕様について聞く

Bean Validationフレームワークの初期ドラフトに関する以前の記事(参考記事)に続き、InfoQは専門家グループが求めているコミュニティの関与と提案について理解を深めるため、Emmanuel Bernard氏と対談しました。

InfoQ: 私は、この仕様でアノテーションと同様にある種のXMLモデルもサポートされるだろうと思っていましたが、そうではないようですね。このことから手を引いているのですか?

Emmanuel Bernard (EB): この仕様でXMLモデルはサポートされることになるでしょう。しかし、XML記述子に取り組むプロセスに入る前に、私たちはまず機能セットとメタモデルを解決したいと思いました。アノテーションはJSR 303 Bean Validation実装の内部モデルとして使用できます。一度アノテーションモデルを正しく定義したら、XMLは単なる他言語の転置(transposition)に近いものになるはずです。

InfoQ: エラーメッセージの階層をサポートする予定はありますか? つまり、一般的なエラーメッセージを表示する標準的な方法があって、必要に応じてページ/画面特有のエラーメッセージでオーバーライドすることができますか?

EB: あなたの質問を理解できているか分かりませんが、2つの観点から答えさせてください。
a) Bean Validation仕様では、従来のファイルシステムベースのResourceBundleローカライゼーションを通じて制約エラーメッセージを外部化およびインターナショナライズ(国際化)できます。制約は「ハードコードされた」メッセージを使用するのではなくキーを宣言できます。

@Length(max = 50, message="{constraint.name.tooLong}")
String name;

## French resourceBundle constraint.name.tooLong =
Le nom ne peut dépasser {max} caractères

このモデルを超えてアプリケーションまたはプレゼンテーションフレームワーク(たとえばWebフレームワーク)との自然な統合を提供するために、メッセージ解決ストラテジーは完全に組み込み可能です。

例を挙げてみましょう。Web Beansはコンテキスト依存コンポーネント(イベント、ページ、要求、会話、ビジネスプロセスなど)の考えを促進します。Web BeansはBean Validationを使用し、コンテキストを意識したメッセージ解決ストラテジーを組み込むことができます。これにより、コンテキスト表現を含むエラーメッセージは解決されることになります。

別の例を挙げてみましょう。Wicketリソースバンドル解決は階層的に定義されます。これはまず、パネルリソースファイル内、次にページリソースファイル内、最終的にアプリケーションリソースファイル内でキーを探そうとします。Wicketは、このパターンに従う独自のメッセージ解決実装を提供できます。

どちらの場合も、コンテキスト情報は適切なエラーメッセージを提供するために極めて重要です。Bean Validation呼び出し側は、このコンテキストを把握するのにより良い状況にいます。カスタムメッセージ解決実装を提供することで、検証作業をBean Validationに任せたまま、自然かつ同質のエクスペリエンスをユーザに提供します。

b) より哲学的な主張をすると、なぜあなたは特定のページの制約メッセージを変更する必要があるのでしょうか? たいてい、制約メッセージは特定のコンテキストで「カスタマイズ」が必要です。なぜなら、1つの制約に見えるものが実際は、異なるコンテキストに適用された2つの異なる制約であるからです。Bean Validation仕様は、コンテキスト制約を記述するメカニズムを提供します。各制約は1つまたは複数のグループに属します。オブジェクトを検証するとき、検証を適用するコンテキストを選択するためのグループのリストが提供されます。グループのユースケースについては、ブログエントリ(リンク)で説明しています。

InfoQ: インターナショナライゼーション(国際化)と検証に関する一般的な1つの問題は、検証ルールがロケール間で異なる場合がある点です。たとえば、英数字テストが異なることがあります。どのようにこれに対処しますか?

EB: 私が一般的に目にしてきたものは、実際のロケールよりもプロパティ値に多く依存する制約ルールです。住所の標準的な例を挙げると、郵便番号や電話番号の制約は、その住所が属している国によって異なります。

一部の制約は変化しませんが(データベース内のnot null、maximum length)、一部は国によって異なるでしょう。仕様は現在、クラスレベルの制約を提供することでこの問題に対処しています。クラスレベルの制約は、プロパティの1つではなくBeanインスタンスにアクセスでき、複数のプロパティに基づいて制約ロジックを適用します。電話番号検証ロジックはフランスと米国に異なるルールを適用するでしょう。フォーマットルールではなく既存のデータベースに基づいてカナダの電話番号に対し外部サービスを呼び出すことさえあるかもしれません。

これは興味深い問題であり、どんな解決策が必要かについて人々は異なった見方をします。クラスレベルのアプローチは最も優れた柔軟性を提供し、仕様をシンプルなままに保ちます。とはいえ、討論はまだ激しく続いています。意見がありましたら、http://forum.hibernate.org/viewforum.php?f=26にアクセスして遠慮なくお聞かせください。 :)

InfoQ: エラーメッセージを操作するために式言語(Expression Language)を使用できますか? また、メッセージの挿入点はありますか({x}と{y}の間に数字を入力できますか)?

EB: はい、デフォルトのメッセージ解決ストラテジーでは、制約パラメータのインジェクションを可能にします。

@Length(max = 50, message="{constraint.name.tooLong}")
String name;
constraint.name.tooLong = Names must not be longer than {max} characters

結果のメッセージは、「Names must not be longer than 50 characters(名前は50文字よりも長くなってはなりません)」になります。

しかし、これは明らかに専門家グループがフィードバックと提案を求めている領域です。追加のコンテキスト情報を提供するBean Validation feedback forum(リンク)で、いくつかの議論がすでに開始しています。

また、前に説明したように、カスタムメッセージ解決ストラテジーをBean Validationプロバイダに提供できます。これは、既存のWebおよびアプリケーションフレームワークとの自然な統合を提供するための鍵となります。アプリケーションおよびWebフレームワークには、自由に使える情報がBean Validationフレームワークよりも多くあるため、はるかに優れた変数展開と式言語解決を提供できると思います。

InfoQ: エラーメッセージのハイパーリンクをサポートする予定はありますか? ある場合は、ローカライゼーションの問題にどのように対処しますか(たとえば、リンクの配置はロケールによって異なることがあります)?

EB: あなたが述べている内容はプレゼンテーションフレームワークに大きく依存しています。プレゼンテーションフレームワークで提供されるカスタムメッセージ解決ストラテジーは、そのような状況に対処するのに申し分ありません。プレゼンテーションフレームワークにはすべてのコンテキスト知識(URLルート、伝えるパラメータなど)があるからです。

InfoQ: 多言語のシナリオは層の間でどのように扱われるでしょうか? たとえば、バックエンドシステムがエラーをある言語(たとえば英語)で生成するが、そのエラーを広東語などの別の言語でユーザに表示する必要がある場合などです。

EB: これは非常に面白い質問ですが、残念ながら、Bean Validationだけではなく全体としてJava EEプラットフォームが関わるため、私が答えのすべての鍵を握っているわけではありません。
広東語で読まれると予想されるなら、バックエンドシステムはエラーメッセージを英語で生成するべきではありません。仕様ではまだそれについて説明していませんが、専門家グループは、特定の検証呼び出しに使用されるロケールをカスタマイズする能力を提供する予定です(おそらくスレッドベースの伝播モデルを使用します)。アプリケーションフレームワークはクライアント側からサーバー側にロケールを伝える役割を担うことになるでしょう。

お分かりのように、アプリケーションフレームワーク(呼び出し側)とBean Validation間の統合は、優れたユーザエクスペリエンスを提供するための鍵となるでしょう。残念ながら(もしくは幸い)、このJSRは制約の宣言と検証に焦点を合わせています。しかし、専門家グループは全体像を把握しており、消費者が正しく統合できるように、できる限り必要な拡張機能と統合ポイントを提供しようと試みています。

InfoQ: 理想は、同じフレームワークを使用してすべての検証を扱えることです(たとえば、JavaScriptから、アプリケーション層で、データベースに対してなど)。現在の仕様はその目標にどの程度近づいていますか?

EB: 私の意見で、極めて重要なことは、そうした異種の層で同じ制約定義を共有できる能力です。同じ検証フレームワークを再利用できれば、さらに良いでしょう。

Bean Validationは層の不可知論者(agnostic)です。プレゼンテーション層からDAO層までのすべてのJava層が、単に制約検証をBean Validationランタイムに任せることができます。いくつか例を挙げましょう。

  • Java Persistenceは、エンティティがデータベースに追加されるたび、またはデータベース内で更新されるたびに、Bean Validationと呼び出すことができます。
  • ビジネスコンポーネントは、中核のビジネスロジックを適用する前にデータセットに対してBean Validationを呼び出すことができます。
  • プレゼンテーション層は、フォームによって提供されるデータに対し、それをドメインモデルに渡す前に、検証ロジックを呼び出すことができます。
  • このような状況においてBean Validationは、アーキテクチャの様々な部分によって呼び出される検証ランタイムエンジンです。制約はドメインモデルのクラスに配置され、すべての層で共有されるため、全体にわたって同じ検証が適用されます。

Javaを超える層については、より複雑で面白くなります。データベースは良い例です。一部の制約はデータベーススキーマで完全に筋が通っています(not null、lengthなど)。Bean Validation仕様は、メタデータ要求APIを通じて制約の基本的なメタデータ情報の一部を公開します。Java PersistenceはこのAPIに接続し、役立つ情報を引き出して、制約をデータベーススキーマに適用できます。

プレゼンテーション側では、そして特にWebアプリケーションでは、一部の制約をJavaScriptコードで適用できます。それは、サーバーへの往復回数を減らし、早期のエラーフィードバックにより、優れたユーザエクスペリエンスを提供します。この状況では2つのアプローチが可能です。プレゼンテーションウィジェット(JSFコンポーネントなど)は、Bean Validation要求APIから制約メタデータを引き出し、JavaScriptで同じロジックを適用できます。もちろん、このモデルですべての制約を表現できるわけではありません。制約の一部はクライアント側で適用されます。このアプローチの利点は、クライアント側とサーバー側の両方がドメインモデルからの制約宣言を共有しているため、透過的に一貫した状態を維持するということです。私たちは実際の制約実装を再利用しませんが、メタデータAPIは制約定義を引き出してそれを再利用する方法をいくつか提供します。2つ目のアプローチは、GWTのようなアプローチを使用することです。JavaコードはJavaScriptに変換されます。同じ実装ロジックがクライアント側とサーバー側で共有されます。

InfoQ: では、Webアプリケーションに電話番号フィールドがあると仮定します。このフィールドは必須であり、最大長は40文字で、英数字値だけを受け入れます。JavaScriptを使用してWeb側でフィールド長をチェックすることを望みます。また、データベース側では、CHAR40と定義されたフィールドがあります。Web層から制約検証を調べたい場合、それをどのように行い、何を受け取るのでしょうか? これはJPA 2に対して同じように機能すると思いますか?

EB: あなたが述べている内容は、基本的にJavaの境界を越えて制約をエクスポートしています。それを実現させるには、Javaの世界とWeb/JavaScript作業をリンクするフレームワークに、次のことが必要とされます。

  • Webフォーム入力とドメインモデルプロパティとの間のリンクを把握する。
  • 制約の説明にアクセスできる。

最初の点は、リンクフレームワークの役割です。それは、(たとえばJSFの)式言語を点検することで起こり得ます。フレームワークが(たとえばWicketで)「Java」を話すため、起こり得ます。

2つ目の点は、プロパティから、リンクフレームワークがBean ValidationのメタデータAPIにクエリーを送信して制約のリストを受信できるため、起こります。各制約(検証ロジックの実装を超える)は、事前定義された一連の静的な制約範囲にどのように投影されるかについて説明しています。これは冗長な言い方ですが、つまり、各制約が次のようなことを強制するかしないかについて説明しているということを意味します。

  • null値の禁止、null値の許容を強制するか、しないか
  • 長さの制約を強制するか、しないか
  • 最大値を強制するか、しないか   

等。これには、Bean Validation APIを採用および使用するためにプレゼンテーションフレームワークからの作業が必要ですが、開発者にさらなる価値をもたらします。

Java Persistenceとの統合と、データベーススキーマの生成方法は、ほとんど同じになるでしょう。単に「form input」という単語を「column」に置き換えてください。

InfoQ: この仕様はHibernate Validationの影響をかなり受けていますが、グループ概念はある種の出発点であるように思えます。このアイデアはどこから来たのかと、それがどのように使用されると思うかについて、少しお話してもらえますか?

EB: 仕様は、Hibernate Validationから大いにアイデアを取り入れましたが、さまざまな種類の検証フレームワークからもアイデアを取り入れています。そうは言っても、仕様内の誤りを最小限にする最良の方法は、既存の動作している機能に基づくことでした。実際のところ、仕様内のほとんどの機能は、徹底的に概念実証を行うことによって、または確かにうまく機能するかHibernate Validatorをフォークすることによって、テストされました。

グループ機能がどこでどのように生まれたか正確には知らないので、間違っていたらすみません。私は、Rifleには昔から同じような機能があったことを知っていて、Hibernate Validatorユーザがこの種の機能について質問していたのを覚えています。一般に、制約間の依存関係とグループに関して困難なことは、それらの説明がすぐに非常に冗長かつ複雑になる場合があるということです。仕様は、柔軟性と単純さのバランスを両立させようとしています。その改善を図るために、すでにフィードバックフォーラムでいくつか興味深い議論が開始しています。

グループは次のようないくつものケースで非常に重要です。

  • 制約のサブセットを定義してユースケースごとにグループ化する(ユーザが有効であり、1クリックで購入するのに十分な情報を提供している)
  • ユーザが提供したとおりデータを検証する。すべてのデータが同時に提供されるわけではありません。所定のオブジェクトは部分的にしか検証可能でない場合があります。
  • 制約によっては、他の制約の後に検証しなければならなくて、前の検証にパスしないと検証してはならないものがある。それらに時間やCPUがかかるという理由の場合もありますし、データが「適切な」状態になることを期待するという理由の場合もあります。

グループはこうしたすべてのユースケースに対して宣言的なソリューションを提供します。私たちは、Java Persistence、JSF、Web Beans、アプリケーションフレームワークが、グループ特有の検証を要求する宣言的な方法を提供することになるだろうと予想しています。

InfoQ: 重複の可能性がある範囲で、他の専門家グループとどのように連携しますか? たとえば、JPA2、Web Beansなどにおいてです。

EB: 厳密に言うと、JSR 303とあなたが言及する仕様の間に重複はありませんが、確実に統合の機会があります。統合作業は正式には開始していませんが、303専門家グループのさまざまなメンバーがJPA 2、JSF 2、およびWeb Beans専門家グループのメンバーでもあります。私は、個人的にJPA 2専門家グループの一員であり、これまでJava Persistenceの統合について考えてきました。初期ドラフトの公開により、他の専門家グループが、この統合を実現するためにコメントすることやフィードバックを提供できるようになりました。

InfoQ: あとどのくらいでプロトタイプ実装は利用可能になりますか?

EB: 実際、コミュニティは私たちを打ち負かしています。すでにいくつかの実装を見つけることができます。私は、http://code.google.com/p/agimatec-validation/を知っています。
準拠こそしていませんが(特にAPIについて)、Hibernate Validatorは、この仕様の概念の多くを実装しており、私たちが議論したフロント、バック間の統合モデルを調査しています。

  • Hibernate Coreと統合してデータベーススキーマを同期化する
  • タグを通じてJBoss SeamおよびJSFと統合する。このタグは、残りのアプリケーションフローに渡す前にフォームプロパティに関してHibernate Validatorへの呼び出しをトリガーします。
  • 一部のUIウィジェットはHibernate Validator制約を再利用し、JavaScript呼び出しによってクライアント側でそれらを適用する

InfoQ: Javaコミュニティから何を求めますか?

EB: ぜひ、仕様に関するフィードバックをいただきたいです。

  • どの程度アプリケーション開発者のニーズに合っているか(使いやすさ、ユースケース)
  • どの程度フレームワーク開発者のニーズに合っているか(統合ポイント、再利用性)
  • どのように仕様を改善できるか

従来の電子メールベースのフィードバックシステムから離れ、皆が交流でき、質問でき、代替案を提案できるパブリックフォーラム(リンク)を開始しました。それは、仕様を変更および強化する最高の時です。これまでのところフィードバックは非常に参考になり興味深いものです。この調子で続けてください。 :)

原文はこちらです:http://www.infoq.com/articles/emmanuel_bernard_interview
(このArticleは2008年4月29日に原文が掲載されました)

この記事に星をつける

おすすめ度
スタイル

BT