この章では、ADFモデル検証機能と、JSF検証機能および変換機能をアプリケーションに追加する方法について説明します。また、エラー(検証に起因しないエラーも含む)を処理および表示する方法についても説明します。
この章の内容は次のとおりです。
ADF Business Componentsアプリケーションでは、ほぼすべての検証コードが、エンティティ・オブジェクトの再使用可能な共有ビジネス・ドメイン・レイヤーで定義されます。これにより、エンド・ユーザーが変更できる各ページでビジネス情報が一貫性のある方法で検証されます。また、検証を一元管理することで、管理が容易になります。エンティティ・オブジェクトの宣言的な実行時動作の構成方法の詳細は、6.6項「宣言的な実行時動作の構成」を参照してください。エンティティまたは属性レベルの宣言的な検証規則の指定方法および管理方法の詳細は、6.7項「宣言的な検証規則の使用」を参照してください。カスタム・コードによるエンティティ・オブジェクトの拡張方法の詳細は、9.3項「Method Validatorの使用」を参照してください。
モデル・レイヤーでは、ADFモデル検証規則をコレクションの属性に設定できます。ADF Business Componentsアプリケーションでは、アプリケーション・モジュールのデータ・コントロール以外のデータ・コントロールを使用しないかぎり、ADFモデル検証規則を追加する必要はありません。
ビュー・レイヤーでは、ADF Facesの入力コンポーネントに組込み検証機能が備わっています。UIコンポーネントに検証を設定するには、required
属性を設定するか、組込みADF Facesバリデータの1つを使用します。また、ADFアプリケーションではモデル・レイヤーに検証機能もあるため、属性へのバインディングに検証を設定できます。さらに、ビジネス・ニーズに合せて独自のADF Facesバリデータを作成することもできます。
ADF Facesの入力コンポーネントには、組込み変換機能も備わっています。このため、ユーザーは情報をStrings
として入力できます。アプリケーションは、この情報をDate
などの別のデータ型に自動的に変換できます。逆に、String
以外のデータとして格納されているデータを、表示および更新のためにString
に変換することもできます。
selectInputDate
などの多くのコンポーネントでは、自動的にこの機能が提供されます。また、inputText
のように、コンバータが存在するタイプの属性をデータ・コントロール・パレットからドラッグ・アンド・ドロップすると自動的に組込みADF FacesまたはJSFの参照実装コンバータが追加されるようなコンポーネントもあります。
バリデータまたはコンバータが失敗した場合、関連付けられたエラー・メッセージをユーザーに表示できます。これらのメッセージは、クライアント側で検証できるようにポップアップ・ダイアログ内に表示することも、検証または変換が失敗したコンポーネントの横のページ自体に表示することもできます。
この章では次の内容について説明します。
ADF FacesバリデータおよびADFモデル検証と、アプリケーション内でのその使用方法
ADF Facesコンバータと、アプリケーション内でのその使用方法
エラー・メッセージの様々な表示方法
エラーがADFモデルにより処理され、ADF Facesのエラー・メッセージ・コンポーネントにより表示される方法
ADFアプリケーションによりスローされた例外が処理される方法と、エラー処理プロセスをカスタマイズする方法
図20-1は、統合されたJSFおよびADFのライフサイクルにおいて検証と変換がどのように機能するかを示しています。
データを含むフォームが送信されると、ブラウザは、value
属性がバインドされているUIコンポーネントごとにリクエスト値をサーバーに送信します。リクエスト値は、最初に、JSFのリクエスト値の適用フェーズでコンポーネントのインスタンスに格納されます。値が変換を必要とする場合(たとえば、DateTime
オブジェクトとして格納されている値をString
として表示する場合)、データは適切なタイプに変換されます。データが格納されているコンポーネントのいずれかに対してADF Faces検証を設定した場合、値はモデルに適用される前に、検証処理フェーズで定義済の規則に対して検証されます。
検証または変換が失敗した場合、ライフサイクルはレスポンスのレンダリング・フェーズに進み、対応するエラー・メッセージがページに表示されます。検証および変換が正常に完了した場合は、UpdateModel
フェーズが開始され、検証済および変換済の値を使用してモデルが更新されます。
この時点で、ADFモデル検証規則が存在する場合は、ADFのモデル更新検証フェーズで値がそれらの規則に対して検証されます。ADF Faces検証の場合と同様に、検証が失敗すると、ライフサイクルはレスポンスのレンダリング・フェーズに進みます。詳細は、13.2.3項「実行時に行われる処理: JSFおよびADFのライフサイクル」を参照してください。ADF Business Componentsアプリケーションでは、アプリケーション・モジュールのデータ・コントロール以外のデータ・コントロールを使用しないかぎり、エンティティ・オブジェクトのビジネス・ドメイン・レイヤーに設定されているバリデータで十分であるため、追加のADFモデル検証規則を使用する必要はありません。
検証または変換のエラーが発生すると、検証または変換に失敗したコンポーネント(JSF検証または変換の場合)あるいは属性(ADFモデル検証の場合)により、関連付けられたエラー・メッセージがキューに挿入され、そのコンポーネントまたは属性は無効化されます。次に現在のページが、エラー・メッセージとともに再表示されます。ADF FacesコンポーネントとADFモデルでは両方とも、宣言的にこれらのメッセージを設定する方法が提供されています。ADFアプリケーションで他のエラーが処理される方法の詳細は、20.8項「ADFアプリケーション内の例外の処理と表示」を参照してください。
ユーザーがフィールド内のデータを編集または入力してフォームを送信したときに、設定した規則および条件に対してデータが検証されるように、検証を追加できます。検証が失敗すると、アプリケーションによりエラー・メッセージが表示されます。
これらの規則および条件は、次のいずれかのレイヤーで設定できます。
ビュー・レイヤー: クライアント側の検証が必要な場合、ADF Faces検証を使用できます。多くのADF Facesコンポーネントには、検証を提供する属性が備わっています。詳細は、20.3.1.1.1項「検証属性の使用」を参照してください。さらに、ADF Facesには、クライアント側とサーバー側のどちらでも実行できる個別の検証クラスが用意されています。詳細は、20.3.1.1.2項「JSFおよびADF Facesのバリデータの使用」を参照してください。また、独自のバリデータを作成することもできます。カスタム・バリデータの詳細は、20.4.3項「カスタムJSFバリデータの作成方法」を参照してください。
モデル・レイヤー: デフォルトでは、データ・コントロール・パレットを使用して入力テキスト・コンポーネントを作成すると、そのコンポーネントには、属性のバインディングのvalidator
プロパティにバインドされたaf:validator
タグが含まれます。このバインディングを使用すると、JSFアプリケーションによりJSFの検証処理フェーズでADFモデル検証が実行されます。ADF Business Componentsアプリケーションでは、アプリケーション・モジュールのデータ・コントロール以外のデータ・コントロールを使用しないかぎり、追加のADFモデル検証規則を使用する必要はありません。ADFモデル検証を使用するには、コレクションの属性へのバインディングに検証規則を宣言的に設定します。詳細は、20.3.1.2項「ADFモデル検証の追加」を参照してください。
ビジネス・レイヤー: ビジネス・レイヤーにおけるエンティティ・オブジェクトの宣言的な検証規則や、エンティティ・オブジェクト属性を設定します。検証をエンティティ・オブジェクトのビジネス・ドメイン・レイヤーに配置することで、属性の値がページによってアクセスされるときに検証を再使用できます。可能であれば、すべての検証規則を、ビジネス・ドメイン・レイヤー内の再使用と管理が容易で一元管理されたエンティティ・オブジェクトに配置することを検討してください。
この章では、ADF FacesバリデータおよびADFモデル検証についてのみ説明します。ADF Business Componentsの宣言的な検証規則の使用方法の詳細は、6.7項「宣言的な検証規則の使用」を参照してください。独自のカスタム規則およびコードによる宣言的な規則の基本セットの使用方法および拡張方法の詳細は、9.3項「Method Validatorの使用」を参照してください。
JSFページでADF Faces検証を設定し、ページ定義ファイルでADFモデル検証を設定します。どちらの検証も、メッセージ表示はJSFページ上で処理されます。検証エラーにより作成されるメッセージの表示方法の詳細は、20.7項「エラー・メッセージの表示」を参照してください。
デフォルトでは、ADF Faces検証はクライアント側とサーバー側の両方で行われます。構文検証およびセマンティク検証はいずれもクライアント側およびサーバー側で実行されますが、クライアント側は、サーバー側で実行される検証のサブセットのみを実行します。クライアント側の検証では、バリデータは、サーバーとの間をラウンドトリップしなくてもデータを取得して表示できます。
クライアント側検証が実行されないようにADF Facesを設定するには、adf-faces-config.xml
内に<client-validation-disabled>
要素を追加し、それをtrue
に追加します。
ADF Facesでは、次のタイプの検証を実行できます。
UIコンポーネント属性: ADF Faces入力コンポーネントには、データの検証に使用できる属性が備わっています。たとえば、ADF Faces入力コンポーネントのrequired
属性を使用して簡単な検証を提供すると、値の入力を必須にするかどうかを指定できます。true
に設定した場合、コンポーネントは値を持つ必要があります。コンポーネントが値を持たない場合、アプリケーションによりエラー・メッセージが表示されます。詳細は、20.3.1.1.1項「検証属性の使用」を参照してください。
デフォルトのADF Facesバリデータ: ADF FacesおよびJSFの参照実装に付属のバリデータでは、日付範囲の検証や入力されたデータの長さの検証など、共通の検証チェックを実行できます。詳細は、20.3.1.1.2項「JSFおよびADF Facesのバリデータの使用」を参照してください。
カスタムのADF Facesバリデータ: 独自のバリデータを作成して、UIコンポーネントに対して使用するように選択できます。詳細は、20.4項「カスタムJSF検証の作成」を参照してください。
多くのADF FacesのUIコンポーネントには、簡単な検証を提供する属性が備わっています。表20-1に、これらの属性、その検証ロジックの説明、およびそれらの属性が含まれるUIコンポーネントを示します。
属性 | 説明 | 対象となるコンポーネント |
---|---|---|
|
|
|
|
|
|
|
表選択コンポーネント(14.6項「表での行選択の有効化」を参照)では、 |
すべての入力コンポーネント、すべての選択コンポーネント、 |
|
入力できる最大文字数。この値は |
|
データ・コントロール・パレットを使用して入力コンポーネントを作成した場合、次のEL式に示すように、required
属性は、関連付けられたバインディングのmandatory
プロパティにバインドされます。
<af:inputText required="#{bindings.ProblemDescription.mandatory}"
このEL式では、バインド先のオブジェクトの属性がnull
になることができるかどうかが評価されます。この式をそのまま保持するように選択することも、required
属性を手動でtrueまたはfalseに設定することもできます。
ヒント: UIコンポーネントがバインドされるオブジェクトは、入力コンポーネントが作成された方法によって異なります。たとえば、パラメータ・フォームを使用して検索フォームが作成された場合は、属性値はメソッドまたはパラメータ付きアクションに渡されるまではバインディング・コンテナに一時的に格納されるのみであるため、入力コンポーネントは通常、変数にバインドされます。コレクションを使用してフォームが作成された場合は、入力コンポーネントは通常、エンティティ・オブジェクトの属性にバインドされます。 |
検証を提供するUIコンポーネント属性を使用する手順:
構造ウィンドウで、UIコンポーネントを選択します。
プロパティ・インスペクタで、検証属性の値を入力します。使用可能な検証属性のリストは、表20-1を参照してください。
(オプション)ユーザーが正しいデータ(数値の場合は有効な範囲など)を入力できるように導くテキストを表示する場合は、tip
属性を設定します。このテキストは、コンポーネントの下に表示されます。
(オプション)required
属性をtrue
に設定した場合(または、true
に評価可能なEL式を使用した場合)は、RequiredMessageDetail
属性の値も入力できます。検証が失敗した場合、ADF Facesでは、デフォルト・メッセージのかわりにこのメッセージが表示されます。
選択コンポーネントがrequired
に設定されている表の場合、エラー・メッセージを表示するには、表のsummary
属性にエラー・メッセージを挿入する必要があります。
メッセージには、パラメータのオプションのプレースホルダ({0}、{1}など)を含めることができます。実行時、プレースホルダは適切なパラメータ値で置き換えられます。パラメータの順序は次のとおりです。
コンポーネント・ラベル入力値(存在する場合)
最小値(存在する場合)
最大値(存在する場合)
パターン値(存在する場合)
例20-1に、パラメータを使用するRequiredMessageDetail
属性を示します。
例20-1 RequiredMessageDetail属性内のパラメータ
<af:inputText value="#{bindings.productId.inputValue}" label="Product ID" requiredMessageDetail="You must enter a {0}." required="true" </af:inputText>
このメッセージは、You must enter a Product ID
に評価されます。
プロパティ・インスペクタでUIコンポーネント属性の追加のヘルプを表示するには、属性名を右クリックして「ヘルプ」を選択します。
JSFおよびADF Facesのバリデータでは、より複雑な検証ルーチンが提供されます。表20-2に、タグを含むJSFの参照実装バリデータを示します。
バリデータ | タグ名 | 説明 |
---|---|---|
|
|
コンポーネント値が、指定された範囲内にあることを検証する。値は、浮動小数点タイプまたは浮動小数点に変換可能である必要がある。 |
|
|
コンポーネント値の長さが、指定された範囲内にあることを検証する。値は、タイプ |
|
|
コンポーネント値が、指定された範囲内にあることを検証する。値は、任意の数値タイプか、 |
表20-3に、ADF Facesに付属の組込みバリデータおよびタグを示します。
表20-3 ADF Facesのバリデータ
バリデータ | タグ名 | 説明 |
---|---|---|
|
|
Javaエンコーディングの使用時に 文字列の格納に必要なバイト数をサーバーで制限する必要がある場合は、 型が |
|
|
入力された日付が、指定された範囲内にあることを検証する。範囲はバリデータの属性として指定する。 |
|
|
Java正規表現構文を使用してデータを検証する。 |
注意: ADF Facesには、コンポーネントのカスタム・バリデータの登録に使用できるaf:validator タグもあります。カスタム・バリデータの使用方法の詳細は、20.4項「カスタムJSF検証の作成」を参照してください。
デフォルトでは、データ・コントロール・パレットから入力テキスト・コンポーネントとして属性をドロップすると、そのコンポーネントに自動的に |
ADF Facesバリデータを追加する手順:
構造ウィンドウで、バリデータを追加するコンポーネントを右クリックします。
ポップアップ・メニューで「<UIコンポーネント>の中に挿入」→「ADF Faces Core」を選択して、ADF Facesバリデータを挿入します。(JSFの参照実装バリデータを挿入するには、「<UIコンポーネント>の中に挿入」→「JSF Core」を選択します。)
バリデータ・タグ(ValidateDateTimeRangeなど)を選択します。
プロパティ・インスペクタで、属性の値(検証エラーのメッセージなど)を設定します。追加のヘルプは、属性を右クリックして「ヘルプ」を選択すると表示されます。
ADF Facesでは、検証エラー・メッセージの詳細部分をカスタマイズできます。XxxMessageDetail属性の値を設定することで(XxxはmaximumMessageDetail
などの検証エラー・タイプ)、検証が失敗したときにデフォルト・メッセージのかわりにカスタム・メッセージを表示できます。
エンティティ・オブジェクトのビジネス・ドメイン・レイヤーに検証規則をすでに設定している場合は、ADFモデル検証を追加する必要はありません。ADF Business Componentsアプリケーションでは、アプリケーション・モジュールのデータ・コントロール以外のデータ・コントロールを使用しないかぎり、ADFモデル検証を使用する必要はありません。
表20-4に、属性に対して構成できるADFモデル検証規則を示します。
表20-4 ADFモデル検証規則
バリデータ規則名 | 説明 |
---|---|
比較 |
属性の値とリテラル値を比較する。 |
リスト |
値が値リスト内にあるかどうかを検証する。 |
レンジ |
値が値範囲内にあるかどうかを検証する。 |
長さ |
値の文字またはバイト・サイズをサイズおよびオペランド(greater than or equal toなど)に対して検証する。 |
正規表現 |
Java正規表現構文を使用してデータを検証する。 |
規則を作成する属性が含まれるページ定義を開きます。
構造ウィンドウで、属性、リストまたは表バインディングを選択します。
プロパティ・インスペクタで「検証規則の編集」リンクを選択します。
「検証規則の追加」ダイアログで、検証規則を選択し、それに応じて規則を構成します。様々なタイプの規則を作成する際の追加のヘルプは、「ヘルプ」をクリックすると表示されます。
属性をデータ・コントロール・パレットからinputText
コンポーネントとしてドロップするなど、データ・コントロール・パレットを使用して入力テキスト・フィールドを作成すると、JDeveloperにより、次のようにしてADF Faces検証コードがJSFページに自動的に提供されます。
af:messages
タグがafh:body
タグの子として追加されます。
デフォルトでは、globalOnly
属性はfalse
に設定され、message
属性とtext
属性は設定されません。詳細は、20.7項「エラー・メッセージの表示」を参照してください。
次のEL式に示すように、入力フィールドのrequired
属性が、関連付けられた属性バインディングのmandatory
プロパティにバインドされます。
<af:inputText required="#{bindings.ProblemDescription.mandatory}"
この式では、関連付けられたビジネス・オブジェクトの属性に基づいてnull
値が許可されるかどうかが評価されます。デフォルトでは、required
属性がtrue
に評価されるすべてのコンポーネントにはアスタリスクが表示されます。
次に示すように、af:validator
タグが入力コンポーネントの子として追加され、関連付けられたバインディングのvalidator
プロパティにバインドされます。
<af:inputText value="#{bindings.SomeAttribute.inputValue}"...>
<af:validator binding="#{bindings.SomeAttribute.validator}"/>
</af:inputText>
このバインディングにより、クライアント側のJSFライフサイクルで、関連付けられた属性に対して設定したADFモデル検証にアクセスできます。ADFモデル検証を使用しない場合は、af:validator
タグを削除して任意の検証タグを挿入できます。また、どの検証も使用しない場合は、単にこのタグを削除できます。ADFモデル検証のみを使用する場合は、このタグをそのままの状態で保持する必要があります。
ヒント: af:validator タグおよびそのバインディングを削除し、ADFモデル検証を後で追加する場合は、タグをコードに再追加して、binding 属性を、関連付けられた属性のvalidator プロパティにバインドする必要があります。 |
たとえば、SRDemoアプリケーションでの製品の簡単な入力フォームを作成するには、データ・コントロール・パレットから作成フォームとしてProductList
コレクションのようなコレクションをドロップします。例20-2に、このようなコレクションがドロップされた場合にJDeveloperにより作成されるJSFコードを示します。
例20-2 製品作成ページのJSFコード
<afh:body> <af:messages/> <h:form> <af:panelForm> <af:inputText value="#{bindings.ProdId.inputValue}" label="#{bindings.ProdId.label}" required="#{bindings.ProdId.mandatory}" columns="#{bindings.ProdId.displayWidth}"> <af:validator binding="#{bindings.ProdId.validator}"/> <f:convertNumber groupingUsed="false" pattern="#{bindings.ProdId.format}"/> </af:inputText> <af:inputText value="#{bindings.Name.inputValue}" label="#{bindings.Name.label}" required="#{bindings.Name.mandatory}" columns="#{bindings.Name.displayWidth}"> <af:validator binding="#{bindings.Name.validator}"/> </af:inputText> <af:inputText value="#{bindings.Image.inputValue}" label="#{bindings.Image.label}" required="#{bindings.Image.mandatory}" columns="#{bindings.Image.displayWidth}"> <af:validator binding="#{bindings.Image.validator}"/> </af:inputText> <af:inputText value="#{bindings.Description.inputValue}" label="#{bindings.Description.label}" required="#{bindings.Description.mandatory}" columns="#{bindings.Description.displayWidth}"> <af:validator binding="#{bindings.Description.validator}"/> </af:inputText> <f:facet name="footer"> <af:commandButton text="Submit"/> </f:facet> </af:panelForm> </h:form> </afh:body>
各inputText
コンポーネントのrequired
属性が、関連付けられたバインディングのmandatory
プロパティにバインドされていることに注意してください。このEL式では、バインド先のオブジェクトの属性がnull
になることができるかどうかが評価されます。
ユーザーがページを送信すると、ADF Facesのvalidate()
メソッドにより最初に、送信された値でコンポーネントのrequired
属性がtrue
かどうかが確認されます。値がnull
またはゼロ長の文字列であった場合、コンポーネントは無効化されます。この時点では、クライアント側の検証が有効になっているかどうかによって実行される処理が異なります。
クライアント側の検証が有効になっている場合、エラー・メッセージがキューに挿入されます。他のバリデータがコンポーネントに登録されている場合、それらのバリデータはコールされず、現在のページが、エラー・メッセージを示すダイアログとともに再表示されます。
注意: JSFの参照実装バリデータはクライアント側では実行されません。 |
例20-2では、image
属性の値は必須ではありません。ただし、これ以外の値はmandatory
プロパティによって設定されているため、必須です。これは、図20-2に示すように、入力テキスト・フィールドの横にあるアスタリスクによってWebページで示されます。図20-2は、クライアント側検証が有効であり、製品IDのデータが入力されなかった場合に表示されるアラート・ダイアログも示しています。3つの必須フィールドすべてにデータが入力されないと、アラートで3つのエラー・メッセージが表示されます。
送信された値がNULL以外の値か、少なくとも1つの文字からなる文字列値であった場合、検証プロセスは続行され、コンポーネントに設定されているすべてのバリデータが1つずつコールされます。コンポーネントのaf:validator
タグはバインディングのvalidator
プロパティにバインドされるため、モデルに設定されている検証ルーチンもこのときにアクセスされて実行されます。
続いて、プロセスは次のコンポーネントに進みます。すべての検証が正常に完了すると、モデル値更新フェーズが開始され、ローカル値を使用してモデルが更新されます。いずれかの検証が失敗すると、現在のページがエラー・ダイアログとともに再表示されます。
クライアント側検証が無効になっている場合は、すべての検証がサーバー側で実行されます。まず、検証処理フェーズでADF Faces検証が実行されます。エラーが発生した場合、値は無効化され、関連付けられたメッセージがFacesContext
内のキューに追加されます。コンポーネントに対してすべての検証が実行された後、モデル・レイヤーに制御が渡されます。次に、モデル・レイヤーによってモデル更新検証フェーズが実行されます。検証処理フェーズと同様に、エラーが見つかった場合は値が無効化され、関連付けられたメッセージがFacesContext
内のキューに追加されます(検証または変換以外のエラーが処理される方法の詳細は、20.8項「ADFアプリケーション内の例外の処理と表示」を参照してください)。次に、ライフサイクルはレスポンス・レンダリング・フェーズにジャンプし、現在のページが再表示されます。ADF Facesにより自動的に、エラーを生成した入力コンポーネントのラベルの横にエラー・アイコンが表示され、関連付けられたメッセージが入力フィールドの下に表示されます。フィールドにヒントが関連付けられている場合は、ヒントの下にエラー・メッセージが表示されます。図20-3は、サーバー側の検証エラーを示しています。
1つのコンポーネントに対してrequired
属性を設定し、かつバリデータも使用することができます。ただし、required属性をtrue
に設定した場合、値がnull
または長さが0の文字であると、コンポーネントは無効化され、そのコンポーネントに登録されている他のバリデータはコールされません。
コンポーネントが空でも有効になるケースが存在する場合は、この組合せでは問題があることがあります。たとえば、ページに「Cancel」ボタンが含まれている場合、ユーザーはデータを入力しなくても、そのボタンをクリックすればページを閉じることができるようにする必要があります。このようなケースを処理するには、「Cancel」ボタンのコンポーネントのimmediate
属性をtrue
に設定します。この属性により、リクエスト値の適用フェーズでこのアクションが実行されるため、アクションが実行されるたびに検証が省略されます。
この項では、バッキングBeanの検証メソッドを追加する方法と、カスタムJSFバリデータを作成する方法について説明します。Method Validatorを使用してカスタム検証コードをADF Business Componentsで起動する方法や、カスタム・コードを使用して宣言的な規則の基本セットを拡張する方法の詳細は、第9章「エンティティ・オブジェクト内のプログラム的なビジネス・ルールの実装」を参照してください。
カスタム検証ロジックは、単一ページ上のコンポーネントに必要な場合があります。たとえば、日付を入力する個別の入力フィールド(月、日、年フィールド)それぞれが独自のバリデータを持つ場合は、ユーザーが「February 30, 2005」と入力してもエラーは表示されません。このような場合は、検証メソッドをページのバッキングBeanに作成することで、検証でページ上の個別のコンポーネントにアクセスし、日付全体を検証できるようになります。
アプリケーション内部の複数のページで再使用されるカスタム検証ロジックが必要な場合や、クライアント側で検証が実行されるようにする場合は、JSFバリデータ・クラスを実装する必要があります。その後でADF Facesバージョンを作成すれば、クライアント側でバリデータが実行されます。
再使用可能なカスタム検証規則を実装してドメイン・ビジネス・レイヤーの一部として使用する場合は、26.9項「カスタム検証規則の実装」を参照してください。
1つのページ上のコンポーネントに対してカスタム検証が必要な場合は、必要な検証を提供するメソッドをバッキングBean上に作成できます。
バッキングBeanの検証メソッドを追加する手順:
検証が必要となるコンポーネントをJSFページに挿入します。
ビジュアル・エディタで、コンポーネントをダブルクリックして「バインドvalidatorプロパティ」ダイアログを起動します。
「バインドvalidatorプロパティ」ダイアログで、検証メソッドを収容するマネージドBeanを入力または選択するか、「新規」をクリックして新しいマネージドBeanを作成します。ロジックがすでに存在する場合は、提供されたデフォルトのメソッド・シグネチャを使用するか、既存のメソッドを選択します。
ダイアログで「OK」をクリックすると、JDeveloperによりスケルトン・メソッドがコードに追加され、ソース・エディタ内にBeanが開きます。
必要な検証ロジックを追加します。このロジックには、適切な例外をスローするためのjavax.faces.validator.ValidatorException
と、対応するエラー・メッセージを生成するためのjavax.faces.application.FacesMessage
を使用する必要があります。Validator
インタフェースおよびFacesMessage
の詳細は、javax.faces.validator.Validator
およびjavax.faces.application.FacesMessage
のJavadocを参照するか、http://java.sun.com/
にアクセスしてください。
検証メソッドを作成すると、JDeveloperにより、選択したマネージドBeanにスケルトン・メソッドが追加されます。例20-3に、JDeveloperにより生成されるコードを示します。
例20-3 検証メソッドのマネージドBeanコード
public void inputText_validator(FacesContext facesContext, UIComponent uiComponent, Object object) { // Add event code here... }
また、EL式を使用してコンポーネントのvalidator
属性がバッキングBeanの検証メソッドにバインドされます。例20-4に、JDeveloperによりコンポーネントに追加されるコードを示します。
例20-4 カスタム検証メソッドのJSFコード
<af:inputText value="#{bindings.SomeObject.inputValue}"
label="#{bindings.SomeObject.label}"
...
validator="#{backing_MyPage.inputText_validator}">
入力コンポーネントを含むフォームが送信されると、validator
属性がバインドされたメソッドが実行されます。
カスタム・バリデータを作成するには、検証のビジネス・ロジックを記述する必要があります。これには、Validator
インタフェースのvalidate
メソッドをオーバーライドするメソッドを含むValidator
実装を作成してから、カスタム・バリデータをアプリケーションに登録します。また、バリデータのタグを作成したり、af:validator
タグを使用してカスタム・バリデータをそのタグのプロパティとしてネストすることもできます。
その後、クライアント側バージョンのバリデータを作成できます。ADF Facesのクライアント側検証は、サーバー側の標準的な検証と同じように機能します。ただし、クライアント側ではJavaScriptが使用されます。これは、JavaScriptのバリデータ・オブジェクトではValidatorExceptions
をスローでき、validate()
メソッドをサポートしているためです。
注意: JavaScriptform.submit() 関数がコールされた場合、ADF Facesのクライアント側検証のサポートは省略されます。ADF Facesでは、かわりに使用できるsubmitForm() メソッドが用意されています。あるいは、ADF Faces入力コンポーネントのautoSubmit 属性を使用することもできます。 |
javax.faces.validator.Validator
インタフェースを実装するJavaクラスを作成します。実装には、引数のないpublicなコンストラクタ、属性に対するアクセッサ・メソッドのセット、およびValidator
インタフェースのvalidate
メソッドをオーバーライドするvalidate
メソッドを含める必要があります。
validate
メソッドは、FacesContext
インスタンス、UIコンポーネント、および検証の対象となるデータを取ります。たとえば、次のように入力します。
public void validate(FacesContext facesContext, UIComponent uiComponent, Object object) { .. }
これらのクラスの詳細は、Javadocを参照するか、http://java.sun.com/
にアクセスしてください。
必要な検証ロジックを追加します。このロジックには、適切な例外をスローするためのjavax.faces.validator.ValidatorException
と、対応するエラー・メッセージを生成するためのjavax.faces.application.FacesMessage
を使用する必要があります。Validator
インタフェースおよびFacesMessage
の詳細は、javax.faces.validator.Validator
およびjavax.faces.application.FacesMessage
のJavadocを参照するか、http://java.sun.com/にアクセスしてください。
注意: ページ作成者がそのページから属性を構成できるようにするには、バリデータのタグを作成する必要があります。詳細は、手順5を参照してください。ページ上に属性を構成しない場合は、この実装クラス内に属性を構成する必要があります。 |
アプリケーションでクライアント側の状態を保存する場合は、カスタム・バリデータ実装にSerializable
インタフェースを実装するか、StateHolder
インタフェースとStateHolder
のsaveState(FacesContext)
メソッドおよびrestoreState(FacesContext, Object)
メソッドを実装します。詳細は、javax.faces.component
パッケージのStateHolder
インタフェースのJavadocを参照してください。
faces-config.xml
ファイル内でバリデータを登録します。
faces-config.xml
ファイルを開き、エディタ・ウィンドウ内で「概要」タブを選択します。faces-config.xml
ファイルは<View_Project>/WEB-INF
ディレクトリ内にあります。
ウィンドウ内で「バリデータ」を選択し、「新規」をクリックします。「ヘルプ」をクリックするか、[F1]を押すと、バリデータの登録に関する追加のヘルプが表示されます。
オプションで、クラスの属性を設定するバリデータのタグを作成します。タグを作成するには、アプリケーションのタグ・ライブラリ定義ファイル(TLD)内にタグのエントリを追加します。この手順は次のとおりです。
アプリケーションのTLDを開くか、作成します。TLDの作成方法の詳細は、http://java.sun.com/にアクセスしてください。
faces-config.xml
ファイル内に登録されているバリデータIDとクラスを定義します。
その構成ファイル内に登録されているプロパティまたは属性を定義します。
注意: バリデータのタグを作成しない場合は、Validator 実装内に属性を構成する必要があります。 |
JavaScriptバージョンのバリデータを作成し、関連する情報をコンストラクタに渡します。
2つのメソッドを持つインタフェースoracle.adf.view.faces.validator.ClientValidator
を実装します。最初のメソッドは、JavaScriptのValidator
オブジェクトの実装を戻すgetClientScript()
です。2つ目のメソッドは、バリデータのインスタンスのインスタンス化に使用されるJavaScriptコンストラクタを戻すgetClientValidation()
です。
クライアント側検証をバリデータ実装に追加する方法の完全な例については、「Development Guidelines for Oracle ADF Faces Applications」の「Client-Side Converters and Validators」を参照してください。
JSFページでタグを持つカスタム・バリデータを使用するには、コンポーネントのタグ内部にそのバリデータを手動でネストする必要があります。
例20-5に、inputText
コンポーネント内にネストされたカスタム・バリデータを示します。faces-config.xml
ファイル内に宣言されていたバリデータのプロパティの値を提供するためにタグ属性が使用されていることに注意してください。
例20-5 JSFページ上のカスタム・バリデータ・タグ
<h:inputText id="empnumber" required="true"> <hdemo:emValidator emPatterns="9999|9 9 9 9|9-9-9-9" /> </h:inputText>
カスタム・タグを持たないカスタム・バリデータを使用する手順:
カスタム・タグを持たないカスタム・バリデータを使用するには、af:validator
タグ内部に(faces-config.xml
ファイル内に構成されている)バリデータのIDをネストする必要があります。
構造ウィンドウから、検証を追加する入力コンポーネントを右クリックし、「<コンポーネント>の中に挿入」→「ADF Faces Core」→「バリデータ」を選択します。
ドロップダウン・リストからバリデータのIDを選択し、「OK」をクリックします。
JDeveloperにより、バリデータIDをvalidator
タグのプロパティにするコードがJSFページに挿入されます。
例20-6に、JSFページでのaf:validator
タグを使用するバリデータのコードを示します。
カスタムJSFバリデータを使用すると、アプリケーションは、カスタム・タグまたはaf:validator
タグ内で参照されているバリデータ・クラスにアクセスし、validate
メソッドを実行します。このメソッドは、現在のFacesContext
内のコンポーネントからデータにアクセスし、そのデータに対してロジックを実行してデータが有効かどうかを判断します。バリデータが属性を持つ場合、それらの属性もアクセスされ、検証ルーチンで使用されます。標準的なバリデータと同様に、カスタム検証が失敗した場合は、関連付けられたメッセージがFacesContext
内のメッセージ・キューに挿入されます。
Webアプリケーションは、モデル・レイヤー内に多くのタイプのデータ(int
、long
、date
など)を格納できます。ただし、クライアント・ブラウザで表示されるとき、ユーザー・インタフェースには、ユーザーが読取りまたは変更できるような形式でデータが表示される必要があります。たとえば、フォーム内の「date」フィールドでは、java.util.Date
オブジェクトがmm/dd/yyyy
という書式パターンのテキスト文字列として表示されるようにします。ユーザーが「date」フィールドを編集してフォームを送信した場合、文字列は、アプリケーションで要求されるタイプに変換される必要があります。変換後のデータは、規則および条件に対して検証されます。
コンバータが存在するタイプの属性をドロップしてinputText
コンポーネントを作成すると、JDeveloperにより、そのコンバータのタグが入力コンポーネントの子として自動的に追加されます。このタグによりコンバータが起動され、ユーザーが入力したString
は、オブジェクトにより期待されるタイプに再び変換されます。
JSF標準コンバータは、Strings
型と単純なデータ型の間の変換を扱い、javax.faces.convert.Converter
インタフェースを実装します。次のJSF標準コンバータ・クラスが提供されています。
BigDecimalConverter
BigIntegerConverter
BooleanConverter
ByteConverter
CharacterConverter
DateTimeConverter
DoubleConverter
FloatConverter
IntegerConverter
LongConverter
NumberConverter
ShortConverter
表20-5に、ADF Facesにより提供されるコンバータを示します。
コンバータ | タグ名 | 説明 |
---|---|---|
|
|
|
|
|
|
|
|
|
バリデータの場合と同様に、ADF Facesコンバータも、adf-faces-config.xml
ファイル内でクライアント側検証が明示的に無効化されていないかぎり、クライアント側で実行されます。
注意: JSFの参照実装コンバータはクライアント側では実行されません。 |
ADF Facesでは、色、日付および数値に対するJavaScript対応コンバータだけでなく、次のいずれかのJavaタイプにバインドされる入力テキスト・フィールドに対するJavaScript対応コンバータも提供されます。
java.lang.Integer
java.lang.Long
java.lang.Short
java.lang.Byte
java.lang.Float
java.lang.Double
表20-5にリストされているコンバータとは異なり、JavaScript対応コンバータは、必要な場合に自動的に使用されます。これらのコンバータには、コンポーネント内にネストできるタグは関連付けられていません。
ADF Facesコンバータが存在する属性をデータ・コントロール・パレットからドロップすると、JDeveloperにより、自動的にそのコンバータが入力コンポーネントに追加されます。手動でコンバータを挿入することもできます。
タグを持つADF Facesコンバータを追加する手順:
構造ウィンドウで、コンバータを追加するコンポーネントを右クリックします。
ポップアップ・メニューで「<UIコンポーネント>の中に挿入」→「ADF Faces Core」を選択してADF Facesコンバータを挿入するか、「JSF Core」を選択してJSFコンバータを挿入します。
コンバータ・タグ(ConvertDateTimeなど)を選択します。
プロパティ・インスペクタで、属性の値(変換エラーのメッセージなど)を設定します。追加のヘルプは、属性を右クリックして「ヘルプ」を選択すると表示されます。
ADF Facesでは、変換エラー・メッセージの詳細部分をカスタマイズできます。XxxMessageDetail属性の値を設定することで(XxxはconvertDateMessageDetail
などの変換エラー・タイプ)、変換が失敗したときにデフォルト・メッセージのかわりにカスタム・メッセージを表示できます。
データ・コントロール・パレットを使用して、コンバータでサポートされているタイプの入力フィールドを作成すると、JDeveloperにより、次のようにしてADF Faces変換コードがJSFページに自動的に提供されます。
af:messages
タグがbody
タグの子として追加されます。デフォルトでは、globalOnly
属性はfalse
に設定され、message属性とtext属性は設定されません。詳細は、20.7項「エラー・メッセージの表示」を参照してください。
コンバータ・タグが入力コンポーネントの子として追加されます。
デフォルトでは、pattern
属性は、関連付けられたバインディングのformat
プロパティにバインドされます。format
プロパティにより、ビジネス・レイヤー・オブジェクトに定義されているフォーマット・マスクに従い、#{bindings.someObject.format}
などのEL式を使用して、String
がフォーマットされる方法が決まります。たとえば、convertNumber
コンバータの場合、このプロパティにより10進値が使用されるかどうかが決まります。
たとえば、ProductList
コレクションからProdId
属性をinputText
コンポーネントとしてドロップすると、JDeveloperにより自動的にconvertNumber
コンバータが入力コンポーネントの子として追加されます(例20-7を参照)。
例20-7 JSFページ内のコンバータ・タグ
<af:inputText value="#{bindings.ProductListProdId.inputValue}" required="#{bindings.ProductListProdId.mandatory}" columns="#{bindings.ProductListProdId.displayWidth}"> ... <f:convertNumber groupingUsed="false" pattern="#{bindings.ProductListProdId.format}"/> </af:inputText>
このバインディングは、データ・コントロールそのものに設定されているformat
プロパティに評価されます。
ヒント: 型がDBSequence の主キー属性をデータ・コントロール・パレットからドロップすると、f:convertNumber タグは入力コンポーネントに追加されません。型がNumber の主キーを使用する編集フォームを作成し、この型を後でDBSequence に変更した場合は、前に作成した入力コンポーネントからf:convertNumber タグを削除するか、フォームを再作成する必要があります。DBSequence の詳細は、6.6.3.8項「トリガーによってデータベース順序から割り当てられた主キー値」を参照してください。 |
コンバータが含まれたページをユーザーが送信すると、ADF Facesのvalidate()
メソッドによりコンバータのgetAsObject()
メソッドがコールされ、文字列値が必要なオブジェクト・タイプに変換されます。コンバータがアタッチされておらず、コンポーネントがモデル内のbeanプロパティにバインドされている場合、JSFでは自動的に、beanプロパティと同じデータ型を持つコンバータが使用されます。変換が失敗した場合、送信された値に無効のマークが付けられ、JSFにより、FacesContext
で保持されているキューにエラー・メッセージが追加されます。変換が正常に完了し、コンポーネントにアタッチされているバリデータがない場合、変換された値はローカル値として格納され、後でモデルの更新に使用されます。
特定のビジネス・ニーズに合せて、独自のコンバータを作成できます。カスタムJSFバリデータを作成する場合と同様に、サーバー側で実行されるカスタムJSFコンバータを作成してから、クライアント側で実行できるJavaScriptバージョンを作成できます。ただし、カスタム・バリデータを作成する場合とは異なり、作成できるのはコンバータ・クラスのみです。変換を提供するためにメソッドをバッキングBeanに追加することはできません。
カスタム・コンバータを作成するには、変換のビジネス・ロジックを記述する必要があります。これには、Converter
インタフェースのgetAsObject
およびgetAsString
メソッドをオーバーライドするメソッドを含むConverter
インタフェースの実装を作成してから、カスタム・コンバータをアプリケーションに登録します。次にf:converter
タグを使用し、そのタグのプロパティとしてカスタム・コンバータをネストします。あるいは、そのコンバータにバインドする入力コンポーネントのconverter
属性を使用することもできます。
また、クライアント側バージョンをコンバータを作成することもできます。ADF Facesのクライアント側コンバータは、サーバー側の標準的なJSF変換と同じように機能します。ただし、クライアント側ではJavaScriptが使用されます。これは、JavaScriptのコンバータ・オブジェクトではConverterExceptions
をスローでき、getAsObject
メソッドおよびgetAsString
メソッドをサポートしているためです。
注意: JavaScriptform.submit() 関数がコールされた場合、ADF Facesのクライアント側変換のサポートは省略されます。ADF Facesでは、かわりに使用できるsubmitForm() メソッドが用意されています。あるいは、ADF Faces入力コンポーネントのautoSubmit 属性を使用することもできます。 |
javax.faces.converter.Converter
インタフェースを実装するJavaクラスを作成します。実装には、引数のないpublicなコンストラクタ、属性に対するアクセッサ・メソッドのセット、および(Converter
インタフェースのgetAsObject
メソッドとgetAsString
メソッドをオーバーライドする)getAsObject
メソッドとgetAsString
メソッドを含める必要があります。
getAsObject
メソッドは、FacesContext
インスタンス、UIコンポーネント、および指定されたオブジェクトに変換されるStringを取ります。たとえば、次のように入力します。
public Object getAsObject(FacesContext context, UIComponent component, java.lang.String value){ .. }
getAsString
メソッドは、FacesContext
インスタンス、UIコンポーネント、およびStringに変換されるオブジェクトを取ります。たとえば、次のように入力します。
public String getAsString(FacesContext context, UIComponent component, Object value){ .. }
これらのクラスの詳細は、Javadocを参照するか、http://java.sun.com/にアクセスしてください。
必要な変換ロジックを追加します。このロジックには、適切な例外をスローするためのjavax.faces.converter.ConverterException
と、対応するエラー・メッセージを生成するためのjavax.faces.application.FacesMessage
を使用する必要があります。Converter
インタフェースおよびFacesMessage
の詳細は、javax.faces.converter.Converter
およびjavax.faces.application.FacesMessage
のJavadocを参照するか、http://java.sun.com/にアクセスしてください。
アプリケーションでクライアント側の状態を保存する場合は、カスタム・コンバータ実装でSerializable
インタフェースを実装するか、StateHolder
インタフェースと、StateHolder
のsaveState(FacesContext)
メソッドおよびrestoreState(FacesContext, Object)
メソッドを実装します。詳細は、javax.faces.component
パッケージのStateHolder
インタフェースのJavadocを参照してください。
faces-config.xml
ファイル内でコンバータを登録します。
faces-config.xml
ファイルを開き、エディタ・ウィンドウ内で「概要」タブを選択します。faces-config.xml
ファイルは<View_Project>/WEB-INF
ディレクトリ内にあります。
ウィンドウ内で「コンバータ」を選択し、「新規」をクリックします。「ヘルプ」をクリックするか、[F1]を押すと、コンバータの登録に関する追加のヘルプが表示されます。
クライアント側バージョンのコンバータを作成する手順:
JavaScriptバージョンのコンバータを作成し、関連する情報をコンストラクタに渡します。
2つのメソッドを持つインタフェースoracle.adf.view.faces.converter.ClientConverter
を実装します。最初のメソッドは、JavaScriptのConverter
オブジェクトの実装を戻すgetClientScript()
です。2つ目のメソッドは、コンバータのインスタンスのインスタンス化に使用されるJavaScriptコンストラクタを戻すgetClientConversion()
です。
クライアント側変換をコンバータ実装に追加する方法の完全な例については、「Development Guidelines for Oracle ADF Faces Applications」の「Client-Side Converters and Validators」を参照してください。
JSFページでカスタム・コンバータを使用する手順:
コンバータ・クラスを入力コンポーネントのconverter
属性にバインドします。
例20-8に、inputText
コンポーネントのconverter
属性により参照されるカスタム・コンバータを示します。
例20-8 JSFページ上のカスタム・コンバータ
<af:inputText value="#{bindings.ProductListName.inputValue}"
label="#{bindings.ProductListName.label}"
required="#{bindings.ProductListName.mandatory}"
columns="#{bindings.ProductListName.displayWidth}"
converter="srdemo.MyConverter">
</af:inputText>
注意: カスタム・コンバータがアプリケーション内の特定のデータ型のクラスの下に登録された場合、コンポーネントの値がカスタム・コンバータ・オブジェクトと同じタイプの値バインディングを参照するたびに、JSFでは自動的にそのクラスのコンバータを使用してデータが変換されます。その場合、次のコードSnippetに示すように、converter 属性を使用してコンポーネントのカスタム・コンバータを登録する必要はありません。
<h:inputText value="#{myBean.myProperty}"/> ここで、 |
デフォルトでは、ADF Facesの検証と変換はクライアント側で実行されます。1つのコンポーネントのデータ検証が失敗すると、そのコンポーネントのエラー・メッセージが示されたアラート・ダイアログが表示されます。クライアント側のエラー・メッセージをこのように表示するために、追加の作業を行う必要はありません。図20-4は、required
属性がtrue
に設定された入力コンポーネントに対してデータが入力されなかった場合に表示されるメッセージを示しています。
ADF Facesでは、検証または変換が失敗したときに表示されるメッセージのデフォルト・テキストが用意されています。デフォルトのメッセージを独自のメッセージで置き換えるには、バリデータまたはコンバータのxxxMessageDetail
属性(convertDateMessageDetail
やnotInRangeDetailMessage
など)のテキストを設定するか、EL式を使用してこれらの属性をリソース・バンドルにバインドします。リソース・バンドルの使用方法の詳細は、22.4.1項「アプリケーションを国際化する方法」を参照してください。
データ・コントロール・パレットを使用して入力コンポーネントを作成すると、JDeveloperによりページの最上部にaf:messages
タグが挿入されます。このタグにより、サーバー側で行われた検証に対するキュー内のすべてのエラー・メッセージを、色でオフセットされたボックス内に表示できます。ADF Facesのクライアント側検証を無効にするように選択した場合、これらのエラー・メッセージがADFモデルのエラー・メッセージとともに表示されます。ADFモデルのメッセージが最初に表示されます。メッセージは、af:messages
タグ内と、関連付けられたコンポーネントの傍に表示されます。
図20-5は、ADFモデルの検証規則に対する、説明が長すぎるというエラー・メッセージを示しています。同時に、ADF Facesコンポーネントのrequired
属性の違反に対するエラー・メッセージも表示されています。
af:messages
タグを使用して、ページ最上部のボックス内にサーバー側のエラー・メッセージを表示できます。データ・コントロール・パレットから入力コンポーネントとしての項目をページ上にドロップすると、JDeveloperにより自動的にこのタグが追加されます。
エラー・ボックス内にエラー・メッセージを表示する手順:
構造ウィンドウでaf:messages
タグを選択します。
このタグは、データ・コントロール・パレットから入力ウィジェットをドロップすると自動的に作成されます。ただし、タグの挿入が必要な場合は、次のコードをafh:body
タグに挿入します。
<afh:body> <af:messages globalOnly="false" /> ... </afh:body>
プロパティ・インスペクタで次の属性を設定します。
globalOnly
: デフォルトでは、ADF Facesによってグローバル・メッセージ(コンポーネントに関連付けられていないメッセージ)が表示され、続いて個別のコンポーネント・メッセージが表示されます。ボックス内にグローバル・メッセージのみを表示する場合は、属性をtrue
に設定します。その場合も、関連付けられたコンポーネントの傍にコンポーネント・メッセージが表示されます。
message
: メッセージ・ボックス・タイトルのすぐ下、個別メッセージのリストの上に表示されるメイン・メッセージ・テキスト。
text:
メッセージ・ボックスのデフォルトのタイトルをオーバーライドするテキスト。
クライアント側の検証が無効になっていることを確認します。クライアント側の検証を無効化していない場合、サーバー側の検証は実行されないため、アラート・ダイアログにADF Faces検証エラーがあるかどうかが表示されます。
ADF Faces入力コンポーネントの変換または検証エラーが発生すると、コンポーネントはFacesMessage
オブジェクトを作成し、FacesContext
インスタンスのメッセージ・キューにそれを追加します。レスポンスのレンダリング・フェーズで、ADF Faces入力コンポーネントの組込みメッセージ表示属性を使用して、バリデータまたはコンバータに関連付けられたメッセージが表示されます。この属性により、コンポーネントの横に詳細なエラー・メッセージが表示されます。メッセージはオプションのaf:messages
タグによっても表示されます。このタグを使用すると、メッセージ・ボックス内にすべてのサマリー・メッセージが表示されます。
ADFアプリケーションの一部によりスローされた例外も、JSFページ上で処理および表示されます。デフォルトでは、アプリケーション内でスローされた例外はすべてバインディング・コンテナにより捕捉されます。例外が発生すると、バインディング・コンテナは例外をアプリケーションのアクティブなエラー・ハンドラ(デフォルトではDCErrorHandlerImpl
クラス)にルーティングします。このクラスのReportException(BindingContainer, Exception)
メソッドは、例外を処理のためにバインディング・コンテナに渡します。バインディング・コンテナは、その例外をキャッシュ内の例外リストに挿入することにより処理します。ページ・ライフサイクル中(たとえば、検証中)にページ上に例外が発生すると、それらの例外もバインディング・コンテナにより捕捉されてキャッシュされ、FacesContext
に追加されます。
レンダリングの準備フェーズで、ADFライフサイクルはreportErrors(context)
メソッドを実行します。このメソッドの実装の方法は、表示テクノロジごとに異なります。デフォルトでは、FacesPageLifecycle
クラスのreportErrors
メソッドが次の処理を実行します。
バインディング・コンテナから例外リストにアクセスします。
addError
ヘルパー・メソッドをコールします。このメソッドは、メッセージを作成してFacesContext
に追加します。デフォルトでは、メッセージにJBO例外番号と例外テキストが表示されます。
バインディング・コンテナ内の例外リストをクリアします。
このデフォルトのフレームワークの動作は、カスタマイズできます。たとえば、例外のカスタム・エラー・ハンドラを作成したり、ライフサイクルで例外がレポートされる方法を変更できます。また、1つのページで例外が処理される方法をカスタマイズすることもできます。
デフォルトの例外処理を変更するには、デフォルトのエラー・ハンドラ(DCErrorHandlerImpl
)を拡張します。また、モデル準備フェーズで新しいエラー・ハンドラをコールするカスタムADFライフサイクル・クラスを作成する必要もあります。
また、カスタムADFライフサイクル・クラスを作成して、reportErrors
メソッドをオーバーライドすることにより、ライフサイクルでエラーがレポートされる方法を変更することもできます。
1つのページに対して例外が作成される方法を変更するのみの場合は、そのページにのみライフサイクル・クラスを作成できます。
DCErrorHandlerImpl
クラスを拡張するクラスを作成します。
新規のクラスで、public void reportException(DCBindingContainer, Exception)
メソッドをオーバーライドします。
例20-9に、SRDemoアプリケーションでエラーの処理に使用されるSRDemoErrorHandler
クラスを示します。
例20-9 SRDemoErrorHandlerクラス
public class SRDemoErrorHandler extends DCErrorHandlerImpl{ /** * Constructor for custom error handler. * @param setToThrow should exceptions throw or not */ public SRDemoErrorHandler(boolean setToThrow) { super(setToThrow); } /** * Overridden ADF binding framework method to customize the way * that Exceptions are reported to the client. * Here we set the "append codes" flag to false on each JboException * in the exception (and any detail JboExceptions it contains) * @param bc BindingContainer * @param ex exception being reported */ public void reportException(DCBindingContainer bc, Exception ex) { //Force JboException's reported to the binding layer to avoid //printing out the JBO-XXXXX product prefix and code. disableAppendCodes(ex); super.reportException(bc, ex); } private void disableAppendCodes(Exception ex) { if (ex instanceof JboException) { JboException jboEx = (JboException) ex; jboEx.setAppendCodes(false); Object[] detailExceptions = jboEx.getDetails(); if ((detailExceptions != null) && (detailExceptions.length > 0)) { for (int z = 0, numEx = detailExceptions.length; z < numEx; z++) { disableAppendCodes((Exception) detailExceptions[z]); } } } } }
エラー・ハンドラをグローバルにオーバーライドします。これには、FacesPageLifecycle
を拡張するカスタム・ページ・ライフサイクル・クラスを作成する必要があります。このクラス内で、エラー・ハンドラを設定するpublic void prepareModel(LifecycleContext)
メソッドをオーバーライドします。エラー・ハンドラをカスタム・ハンドラに設定するには、メソッドを使用して、カスタム・エラー・ハンドラがバインディング・コンテキスト内で現行エラー・ハンドラになっているかどうかを確認します。現行エラー・ハンドラになっていない場合は、現行エラー・ハンドラに設定します。(デフォルトでは、ADFBindingFilter
は常にエラー・ハンドラをDCErrorHandlerImpl
に設定するため、メソッドによりそれをカスタム・エラー・ハンドラに戻す必要があります。)次にsuper.prepareModel
をコールする必要があります。
例20-10に、FacesPageLifecycle
クラスを拡張するframeworkExt.SRDemoPageLifecycle
クラスからのprepareModel
メソッドを示します。このメソッドは、エラー・ハンドラがSRDemoErrorHandler
のインスタンスであるかどうかを確認し、そうでない場合にはエラー・ハンドラを新規のエラー・ハンドラに設定することに注意してください。
今度は、カスタム・ライフサイクルを返す新規のフェーズ・リスナーを作成する必要があります。手順については、この後の「新規のフェーズ・リスナーを作成する手順:」を参照してください。
ライフサイクルでエラーがレポートされる方法をカスタマイズする手順:
FacesPageLifecycle
を拡張するカスタム・ページ・ライフサイクル・クラスを作成します。
public void reportErrors(PageLifecycleContext)
メソッドをオーバーライドして、エラー・メッセージの表示をカスタマイズします。
SRDemoでreportErrors()
メソッドを確認します。このメソッドは、frameworkExt.SRDemoPageLifecycle
クラスにあります。このメソッドでは、ユーザーが直接修正できないリストから例外を削除することで、エラー処理をカスタマイズします。一般に、削除されるエラーは、ADF Business Componentsのバンドル例外モードで追加されるラッパー例外です。バンドル例外モードの詳細は、10.5.7項「バンドル例外モードの理解」を参照してください。
今度は、カスタム・ライフサイクルを返す新規のフェーズ・リスナーを作成する必要があります。
ADFPhaseListener
クラスを拡張します。
protected PageLifecycle createPageLifecycle ()
メソッドをオーバーライドして、新規のカスタム・ライフサイクルを戻します。
例20-11に、frameworkExt.SRDemoADFPhaseListener
クラス内のcreatePageLifecycle
メソッドを示します。
faces-config.xml
ファイル内でフェーズ・リスナーを登録します。
faces-config.xml
ファイルを開き、エディタ・ウィンドウ内で「概要」タブを選択します。faces-config.xml
ファイルは<View_Project>/WEB-INF
ディレクトリ内にあります。
ウィンドウ内で「ライフ・サイクル」を選択し、「新規」をクリックします。「ヘルプ」をクリックするか、[F1]を押すと、フェーズ・リスナーの登録に関する追加のヘルプが表示されます。
FacesPageLifecycle
クラスを拡張するカスタム・ページ・ライフサイクルを作成します。
public void reportErrors(PageLifecycleContext)
メソッドをオーバーライドして、エラー・メッセージの表示をカスタマイズします。このメソッドのオーバーライドの例は、前述の「ライフサイクルでエラーがレポートされる方法をカスタマイズする手順:」を参照してください。
ページのページ定義を開きます。構造ウィンドウで、ページ定義ノードを選択します。プロパティ・インスペクタで、ControllerClass
属性の値として新規のクラスを入力します。
独自のエラー・ハンドラを作成すると、アプリケーションではDCErrorHandler
クラスではなくそのクラスが使用されます。新規のライフサイクルを作成して登録したため、そのライフサイクルがアプリケーションに使用されます。この新規のライフサイクルによって、カスタム・エラー・ハンドラがインスタンス化されます。
以降にエラーが見つかると、バインディング・コンテナがエラーをカスタム・エラー・ハンドラにルーティングします。次に、reportException(BindingContainer, Exception)
メソッドが実行されます。
カスタム・ライフサイクル・クラス内のreportErrors
メソッドをオーバーライドした場合は、レンダリング準備フェーズでライフサイクルによって新規のreportErrors(context)
メソッドが実行されます。