Oracle® Fusion Middleware Oracle Application Development FrameworkによるFusion Webアプリケーションの開発 12c (12.1.3) E59441-03 |
|
![]() 前 |
![]() 次 |
この章では、Oracle ADFアプリケーションのADFモデル・レイヤー内で検証ルールを使用する方法について説明します。
この章には、次のセクションがあります。
Modelレイヤーでは、ADFモデル検証規則を特定のページのバインディングの属性として設定できます。ユーザーがフィールド内のデータを編集または入力してフォームを送信したときに、設定した規則および条件に対してバインドされたデータが検証されます。検証が失敗すると、アプリケーションによりエラー・メッセージが表示されます。
エンティティ・オブジェクトのビジネス・ドメイン・レイヤーに検証規則をすでに設定している場合は、ADFモデル検証を追加する必要はありません。ADFビジネス・コンポーネント・ベースのFusion Webアプリケーションでは、アプリケーション・モジュールのデータ・コントロール以外のデータ・コントロールを使用しないかぎり、ADFモデル検証を使用する必要はありません。
アプリケーションでADFビジネス・コンポーネントに基づかないデータ・コントロールを使用している場合は、ADFモデル・レイヤー検証を使用してユーザーが入力したデータの品質を確保できます。
ベスト・プラクティス: 可能な場合はビジネス・レイヤー検証を使用します。ただし、次の例に示すような場合には、モデル・レイヤー検証の使用が必要になる場合があります。
また、サーバーとのラウンドトリップの前に検証を実行する場合、クライアント側の検証を使用することもできます。詳細は、『Oracle ADF FacesによるWebユーザー・インタフェースの開発』の検証ルールの追加に関する項を参照してください。 |
アプリケーションで、ビジネス・レイヤー検証に加えてモデル・レイヤー検証の使用も保証されている場合は、ADFビジネス・コンポーネント・オブジェクトで利用できる宣言的検証機能の多くをモデル・レイヤーでも利用できます。
モデル・レイヤー認証を使用する前に、他のADF検証機能を理解しておくと役立つ場合があります。次に、関連する他の機能へのリンクを示します。
ADFビジネス・コンポーネント・アプリケーション・モジュールのデータ・コントロールを使用する場合、モデル・レイヤー検証を使用する必要はありません。可能であれば、すべての検証規則を、ビジネス・レイヤー内の再使用と管理が容易で一元管理されたエンティティ・オブジェクトに定義することを検討してください。詳細は、第11章「検証とビジネス・ルールの宣言的な定義」を参照してください。
ページ・レベルで利用できる宣言的検証機能の多くは、Beanレベルでも利用できます(その場合はデータ・コントロール構造ファイルで実装します)。データ・コントロール構造ファイルの検証規則は、データ・コントロールが使用されるすべての場合に適用されるため、非常に役立ちます。データ・コントロール構成ファイルで検証ルールを実装する場合の詳細は、『Oracle ADFデータ・コントロールによるアプリケーションの開発』の「データ・コントロールへのビジネス・ロジックの追加」の章を参照してください。
バインディングの属性に対するADFモデル検証は、ページ定義ファイルで構成できます。モデル・レイヤーの検証規則は、特定のページのバインディング属性に対して、その対象を含むフォームの送信時に実行されます。
オプションで、skipValidation
プロパティをtrue
に設定すると、ADFモデル検証をバイパスできます。skipValidation
をskipDataControls
に設定して、トランザクションを検証せずに、バインド・オブジェクトを検証できます。たとえば、データ入力を受け付けるポップアップ・ウィンドウを開く表アクションがあるときに、表でコミットする前にビュー・レイヤーでこれらの入力を検証できるようにする場合は、skipValidation
をskipDataControls
に設定します。skipValidation
プロパティは、「構造」ウィンドウでページ定義ファイルのルート・ノードを選択した後に、「プロパティ」ウィンドウに表示されます。
ADFモデル検証をページ定義ファイルに設定します。検証規則を定義し、規則に違反した場合に表示するエラー・メッセージを設定します。
表18-1に、バインディングの属性に対して構成できるADFモデル検証規則を示します。
表18-1 ADFモデル検証規則
バリデータ規則名 | 説明 |
---|---|
比較 |
属性の値とリテラル値を比較する。 |
リスト |
値が値リスト内にあるかどうかを検証する |
範囲 |
値が値範囲内にあるかどうかを検証する。 |
長さ |
値の文字またはバイト・サイズをサイズおよびオペランド(greater than or equal toなど)に対して検証する。 |
正規表現 |
Java正規表現構文を使用してデータを検証する。 |
必須 |
属性にその値が存在するかどうかを検証する。 |
始める前に:
モデル・レイヤーでの検証規則の使用に関する知識があると役立つ場合があります。詳細は、18.2項「ADFモデル・レイヤーでの検証規則の定義」を参照してください。
また、他の検証機能を使用して追加できる機能についても理解しておくと役立ちます。詳細は、18.1.2項「ADFモデル・レイヤー検証の追加機能」を参照してください。
次のタスクを完了する必要があります。
ページにコンポーネントを作成します。このコンポーネントにはバインディング属性が必要です。
ADFモデル検証規則を作成するには:
「アプリケーション」ウィンドウで、ルールを作成するバインディングを含むページ定義をダブルクリックします。
「構造」ウィンドウで、属性、リストまたは表バインディングを選択します。
「プロパティ」ウィンドウで、「詳細」ドロップダウン・メニューをクリックし、「検証ルールの編集」を選択します。
「検証ルール・エディタ」ダイアログで、バインディング・ノードを開き、属性名を選択して、「新規」をクリックします。
「検証ルールの追加」ダイアログで、検証規則を選択し、必要に応じて規則を構成します。
「失敗処理」タブをクリックして、ルールに違反した場合に表示するメッセージを構成します。
ユーザーがデータを送信すると、送信された値がNULL以外の値か、少なくとも1つの文字からなる文字列値であった場合、コンポーネントに設定されているすべてのバリデータが1つずつコールされます。コンポーネントのf:validator
タグはバインディングのvalidator
プロパティにバインドされるため、モデルに設定されている検証ルーチンがアクセスされて実行されます。
続いて、プロセスは次のコンポーネントに進みます。すべての検証が正常に完了すると、モデル値更新フェーズが開始され、ローカル値を使用してモデルが更新されます。いずれかの検証が失敗すると、現在のページがエラー・メッセージとともに再表示されます。
例外が発生すると、デフォルトの動作ではADF Facesのエラー・ダイアログにリーフレベル・エラーのみ表示されます。ADFコントローラのデフォルトのエラー処理メカニズムは、ページ・バインディング・コンテナから例外のリストを取得し、各エラーの表示方法を決定します。例外がJboException
でない場合、Facesエラー・メッセージが例外メッセージとともに表示されます。
例外がJboException
の場合、エラー処理メカニズムはネストされた例外に再帰的にドリル・ダウンし、一意の例外ごとに単一のFacesエラー・メッセージを表示します。ただし、例外にJboWarning.HIDE_DETAIL_EXCEPTIONS_HINT
がある場合、エラー処理メカニズムはネストされた例外にドリル・ダウンしません。
また、エラー処理メカニズムは、各例外のバインディング・エラーのリストを取得し、エラーをレポートしたバインディングに関連付けられているコンポーネントに対するFacesエラー・メッセージを表示します。
デフォルトのDCErrorHandlerImpl
クラスを拡張するカスタム・エラー・ハンドラを使用して、エラーをレポートできます。カスタム例外ハンドラ・クラスを登録するためにコードを記述する必要はありません。かわりに、「構造」ウィンドウでDataBindings.cpx
ファイルのルート・ノードを選択した後、「プロパティ」ウィンドウを使用してErrorHandlerClass
プロパティに、使用するエラー・ハンドラの完全修飾名を設定します。
カスタム・エラー・ハンドラには、次のオーバーライド可能なメソッドを含めることができます。
reportException()
: 発生した例外をレポートするためにコールされます。レポートされた例外を分析するようにオーバーライドできます。
getDisplayMessage()
: 発生したエラーごとにJSFにレポートされるメッセージを戻します。カスタム・エラー・ハンドラで特定の例外をクライアントにレポートする必要がない場合は、null
を戻します。
getDetailedDisplayMessage()
: 発生したエラーごとにJSFにレポートされるメッセージの詳細部分を、String
オブジェクトまたはHTMLとして戻します。カスタム・エラー・ハンドラで特定の例外をクライアントにレポートする必要がない場合は、null
を戻します。
skipException()
: ユーザー向けに表示される最終的なエラー・リストに、ネストされた例外から各アイテムを表示するかどうかに応じたブール値を戻します。このメソッド・オーバーライドにより、特定の例外タイプをチェックし、ビジネス・シナリオに基づいて、このタイプをリストに表示するかどうかを判断するロジックを実装できます。
例18-1は、DCErrorHandlerImpl
クラスを拡張したカスタム・エラー・ハンドラです。この例は、ユーザーに表示されるリストに載せない例外をスキップするために必要なskipException()
メソッドに対するオーバーライドを示しています。
例18-1 カスタム・エラー・ハンドラ
package view.controller.fwkext; import java.sql.SQLIntegrityConstraintViolationException; import java.util.ArrayList; import java.util.List; import oracle.adf.model.binding.DCBindingContainer; import oracle.adf.model.binding.DCErrorHandlerImpl; import oracle.jbo.CSMessageBundle; import oracle.jbo.DMLConstraintException; import oracle.jbo.JboException; public class CustomErrorHandler extends DCErrorHandlerImpl { List<ExceptionMapper> exceptionMapperList = new ArrayList<ExceptionMapper>(); public CustomErrorHandler() { super(); exceptionMapperList.add(new DisableJboExceptionCodesMapper()); } public void reportException(DCBindingContainer bc, Exception ex) { for (ExceptionMapper mapper : exceptionMapperList) { if (mapper.canMapException(ex)) { ex = mapper.mapException(ex); } } super.reportException(bc, ex); } /** * If an exception is a RowValException or a TxnValException and they * have nested exceptions, then do not display it. This example shows * an implementation that skips the SQLIntegrityConstraintViolationException * from displaying in the error final list displayed to the user. */ @Override protected boolean skipException(Exception ex) { if (ex instanceof DMLConstraintException) { return false; } else if (ex instanceof SQLIntegrityConstraintViolationException) { return true; } return super.skipException(ex); } }
エラー・ハンドラ・クラスには、カスタム・クラスの名前と一致するデフォルトのコンストラクタが必要です。たとえば、カスタム・ハンドラ・クラスMyErrorHandler
を作成した場合、例外エラー・ハンドラは、例18-2に示すようにデフォルトのコンストラクタを起動します。この規則に従うと、クラス名のみで動的な起動が可能になります。
例18-2 デフォルトのコンストラクタ
ErrorHandlerClass="viewcontroller.MyErrorHandler" public MyErrorHandler() { super(); }
メッセージの詳細部分をカスタマイズし、使用する予定のある場合は、このメッセージを取得し、処理するために、カスタム・エラー・ハンドラを作成し、getDetailedDisplayMessage
メソッドを実装することができます。最終的なメッセージは、ビュー・レイヤーに渡され、他のメッセージと統合されます。
メッセージの詳細部分をカスタマイズするには:
デフォルトのDCErrorHandlerImpl
クラスを拡張するカスタム・エラー・ハンドラを作成します。
このクラスで、DCErrorMessage
オブジェクトを戻すgetDetailedDisplayMessage
メソッドをオーバーライドします。
例18-3に、カスタム・エラー・ハンドラ・クラスでのgetDetailedDisplayMessage
メソッドの実装を示します。
例18-3 getDetailDisplayMessageメソッドを使ったカスタム・エラー・ハンドラ・クラス
public final class MyErrorMessageHandler extends DCErrorHandlerImpl { public MyErrorMessageHandler (){ super(); } public DCErrorMessage getDetailedDisplayMessage(BindingContext ctx, RegionBinding ctr, Exception ex) { ... return new MyDCErrorMesssage(ctr, ex); } }
DCErrorMessage
インタフェースを実装するカスタム・クラスを作成します。このクラスはgetHTMLText
メソッドおよびgetText
メソッドを実装する必要があります。
getHTMLText
メソッドに、実際の処理を実行するためのコードを追加しますが、インタフェースの要件を満たすには、getText
の実装も必要です。
getHTMLText
の実装では、エラー・メッセージを作成、処理するためのコードを追加します。
getDetailedDisplayMessage
のgetHTMLText
は、エラー・メッセージの最終版をHTMLフラグメントとして戻す必要があります。このフラグメントは、ページのHTMLコードに挿入されます。このため、getDetailedDisplayMessage
によりメッセージが戻される前に、テキスト・メッセージに対して、必要な前処理をすべて実行しておく必要があります。たとえば、ローカライズしたメッセージの取得や、メッセージの順番を右から左に変更するなどの処理が必要である場合は、メッセージが戻される前に行います。
例18-4はこのインタフェースの実装を示しています。
例18-4 DCErrorMessageインタフェースの実装
public final class MyDCErrorMesssage implements DCErrorMessage { RegionBinding m_regionBinding; Exception m_ex; public MyDCErrorMesssage(RegionBinding ctr, Exception ex) { super(); this.m_regionBinding = ctr; this.m_ex = ex; } public String getText() { ... return "Message String"; } public String getHTMLText() { ... /* Add code to process the message, including localization */ /* and right-to-left directional requirements. */ /* Return the message as the finalized HTML fragment.*/ return "<html><b>error</b> message details</html>"; } }
HTMLタグを使用してメッセージを書式化するには、例に示すように、メッセージを<html></html>
タグで囲む必要があります。エラー・メッセージでは次のHTMLタグのみを使用できます。
<span>
<b>
<a>
<i>
<em>
<br>
<hr>
<li>
<ol>
<ul>
<p>
<tt>
<big>
<small>
<pre>
エラー・ハンドラを使用すると、ADFモデル・レイヤーのカスタム検証を使用してアプリケーションの警告に対して情報メッセージを表示できます。モデル・レイヤー検証を使用するアプリケーションでは、すべてのエラーと警告について、アプリケーションCPXレベルでカスタム・エラー・ハンドラを使用する必要があります。
始める前に:
モデル・レイヤーでのカスタム検証の動作に関する知識があると役立つ場合があります。詳細は、18.3項「エラー処理のカスタマイズ」を参照してください。
また、他の検証機能を使用して追加できる機能についても理解しておくと役立ちます。詳細は、18.1.2項「ADFモデル・レイヤー検証の追加機能」を参照してください。
JDeveloperを起動し、カスタム・エラー・ハンドラを追加するアプリケーションを開く必要もあります。
情報メッセージを表示する手順
データ・モデル・プロジェクトで、JboWarning
を拡張するクラスを作成します。次に例を示します。
public class InformationalMessage extends JboWarning { public static final String INFO_PROPERTY = "$InformationalMessage$INFO"; public InformationalMessage(String message) { super(message, "", new Object[]{INFO_PROPERTY}); } }
アプリケーション・モジュール実装クラスで、メソッドを追加し、クライアント・メソッドとして公開します。次に例を示します。
public void addInformationMessageTest() { addWarning (new InformationalMessage("Testing. This is an information message")); }
18.3項「エラー処理のカスタマイズ」で説明するように、ビュー・コントローラ・プロジェクトで、カスタム・エラー・ハンドラ・クラスを作成します。
作成したカスタム・エラー・ハンドラをデータ・バインディング・ファイル(DataBindings.cpx
)に追加します。次に例を示します。
<Application xmlns="http://xmlns.oracle.com/adfm/application"
id="DataBindings" SeparateXMLFiles="false"
Package="my.view" ClientType="Generic"
ErrorHandlerClass="my.view.CustomErrorHandler">
<pageMap>
<page path="/Test.jspx" usageId="my_view_TestPageDef"/>
</pageMap>
メソッドをテストするには、クライアント・アプリケーション・モジュール・メソッドを.jspx
ページにコマンド・ボタンとしてドロップして、情報メッセージを呼び出すことができます。
.jspx
ファイルを実行し、ボタンを押すと、情報メッセージが表示されます。
Oracle ADFでは、作成されるBindingContext
オブジェクトごとにカスタム・エラー・ハンドラのインスタンスを1つ作成します。Oracle ADFでは、同じ論理エンド・ユーザー・セッションからの同時Webリクエストをシリアライズするため、通常、複数スレッドは同じエラー・ハンドラを同時に使用しません。しかし、スレッドセーフのカスタム・エラー・ハンドラを保証するには、JboException
でsetProperty()
APIを使用します。このメソッドは、表示用に例外がJSF FacesMessage
オブジェクトに変換されるときに、後で必要になる可能性があるヒントをすべて例外オブジェクト自体に格納します。