ヘッダーをスキップ
Oracle Application Development Framework Forms/4GL開発者のための開発者ガイド
10g(10.1.3.0)
B40013-02
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 

20 検証と変換の使用

この章では、ADFモデル検証機能と、JSF検証機能および変換機能をアプリケーションに追加する方法について説明します。また、エラー(検証に起因しないエラーも含む)を処理および表示する方法についても説明します。

この章の内容は次のとおりです。

20.1 検証と変換の概要

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の参照実装コンバータが追加されるようなコンポーネントもあります。

バリデータまたはコンバータが失敗した場合、関連付けられたエラー・メッセージをユーザーに表示できます。これらのメッセージは、クライアント側で検証できるようにポップアップ・ダイアログ内に表示することも、検証または変換が失敗したコンポーネントの横のページ自体に表示することもできます。

この章では次の内容について説明します。

20.2 検証、変換およびアプリケーション・ライフサイクル

図20-1は、統合されたJSFおよびADFのライフサイクルにおいて検証と変換がどのように機能するかを示しています。

図20-1 ライフサイクルにおける検証と変換

検証と変換を処理するフェーズ

データを含むフォームが送信されると、ブラウザは、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アプリケーション内の例外の処理と表示」を参照してください。

20.3 検証の追加

ユーザーがフィールド内のデータを編集または入力してフォームを送信したときに、設定した規則および条件に対してデータが検証されるように、検証を追加できます。検証が失敗すると、アプリケーションによりエラー・メッセージが表示されます。

これらの規則および条件は、次のいずれかのレイヤーで設定できます。

この章では、ADF FacesバリデータおよびADFモデル検証についてのみ説明します。ADF Business Componentsの宣言的な検証規則の使用方法の詳細は、6.7項「宣言的な検証規則の使用」を参照してください。独自のカスタム規則およびコードによる宣言的な規則の基本セットの使用方法および拡張方法の詳細は、9.3項「Method Validatorの使用」を参照してください。

20.3.1 検証の追加方法

JSFページでADF Faces検証を設定し、ページ定義ファイルでADFモデル検証を設定します。どちらの検証も、メッセージ表示はJSFページ上で処理されます。検証エラーにより作成されるメッセージの表示方法の詳細は、20.7項「エラー・メッセージの表示」を参照してください。

20.3.1.1 ADF Faces検証の追加

デフォルトでは、ADF Faces検証はクライアント側とサーバー側の両方で行われます。構文検証およびセマンティク検証はいずれもクライアント側およびサーバー側で実行されますが、クライアント側は、サーバー側で実行される検証のサブセットのみを実行します。クライアント側の検証では、バリデータは、サーバーとの間をラウンドトリップしなくてもデータを取得して表示できます。


注意:

JSFページでJavaScript form.submit()関数がコールされた場合、ADF Facesのクライアント側検証のサポートは省略されます。ADF Facesでは、かわりに使用できるsubmitForm()メソッドが用意されています。あるいは、ADF Faces入力コンポーネントのautoSubmit属性を使用することもできます。

クライアント側検証が実行されないように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検証の作成」を参照してください。

20.3.1.1.1 検証属性の使用

多くのADF FacesのUIコンポーネントには、簡単な検証を提供する属性が備わっています。表20-1に、これらの属性、その検証ロジックの説明、およびそれらの属性が含まれるUIコンポーネントを示します。

表20-1 ADF Facesの検証属性

属性 説明 対象となるコンポーネント

maxValue

Date値に使用可能な最大値。

chooseDate

minValue

Date値に使用可能な最小値。

chooseDate

required

trueに設定した場合(またはtrueに評価されるEL式に設定した場合)、コンポーネントは、少なくとも1つの文字に対して非NULL値またはString値を持つ必要がある。

表選択コンポーネント(14.6項「表での行選択の有効化」を参照)では、required属性をtrueに設定した場合、表内の少なくとも1行が選択される必要がある。

すべての入力コンポーネント、すべての選択コンポーネント、tableSelectManytableSelectOne

maximumLength

入力できる最大文字数。この値はcolumns属性に設定された値には依存しないことに注意。表20-3「ADF Facesのバリデータ」ByteLengthValidatorも参照。

inputText


データ・コントロール・パレットを使用して入力コンポーネントを作成した場合、次のEL式に示すように、required属性は、関連付けられたバインディングのmandatoryプロパティにバインドされます。

<af:inputText required="#{bindings.ProblemDescription.mandatory}"

このEL式では、バインド先のオブジェクトの属性がnullになることができるかどうかが評価されます。この式をそのまま保持するように選択することも、required属性を手動でtrueまたはfalseに設定することもできます。


ヒント:

UIコンポーネントがバインドされるオブジェクトは、入力コンポーネントが作成された方法によって異なります。たとえば、パラメータ・フォームを使用して検索フォームが作成された場合は、属性値はメソッドまたはパラメータ付きアクションに渡されるまではバインディング・コンテナに一時的に格納されるのみであるため、入力コンポーネントは通常、変数にバインドされます。コレクションを使用してフォームが作成された場合は、入力コンポーネントは通常、エンティティ・オブジェクトの属性にバインドされます。

検証を提供するUIコンポーネント属性を使用する手順:

  1. 構造ウィンドウで、UIコンポーネントを選択します。

  2. プロパティ・インスペクタで、検証属性の値を入力します。使用可能な検証属性のリストは、表20-1を参照してください。

  3. (オプション)ユーザーが正しいデータ(数値の場合は有効な範囲など)を入力できるように導くテキストを表示する場合は、tip属性を設定します。このテキストは、コンポーネントの下に表示されます。

  4. (オプション)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コンポーネント属性の追加のヘルプを表示するには、属性名を右クリックして「ヘルプ」を選択します。

20.3.1.1.2 JSFおよびADF Facesのバリデータの使用

JSFおよびADF Facesのバリデータでは、より複雑な検証ルーチンが提供されます。表20-2に、タグを含むJSFの参照実装バリデータを示します。

表20-2 JSFの参照実装バリデータ

バリデータ タグ名 説明

DoubleRangeValidator

f:validateDoubleRange

コンポーネント値が、指定された範囲内にあることを検証する。値は、浮動小数点タイプまたは浮動小数点に変換可能である必要がある。

LengthValidator

f:validateLength

コンポーネント値の長さが、指定された範囲内にあることを検証する。値は、タイプjava.lang.Stringである必要がある。

LongRangeValidator

f:validateLongRange

コンポーネント値が、指定された範囲内にあることを検証する。値は、任意の数値タイプか、longに変換可能なStringである必要がある。


表20-3に、ADF Facesに付属の組込みバリデータおよびタグを示します。

表20-3 ADF Facesのバリデータ

バリデータ タグ名 説明

ByteLengthValidator

af:validateByteLength

Javaエンコーディングの使用時にString内のバイト数を検証する。たとえば、英語の6文字と日本語の6文字では、格納に使用するバイト数が異なる。バリデータの属性として、使用するエンコーディングを指定する。

文字列の格納に必要なバイト数をサーバーで制限する必要がある場合は、maximumLength属性を入力コンポーネントに指定するかわりに、このバリデータを使用する。

型がVARCHAR2(n)のOracleデータベース表列では、マルチバイト・キャラクタ・セットの使用時に、データベースのVARCHAR2のサイズが文字とバイトのどちらのサイズを示すかによって、最大許容バイト長はnではない場合がある。

DateTimeRangeValidator

af:validateDateTimeRange

入力された日付が、指定された範囲内にあることを検証する。範囲はバリデータの属性として指定する。

RegExpValidator

af:validateRegExp

Java正規表現構文を使用してデータを検証する。



注意:

ADF Facesには、コンポーネントのカスタム・バリデータの登録に使用できるaf:validatorタグもあります。カスタム・バリデータの使用方法の詳細は、20.4項「カスタムJSF検証の作成」を参照してください。

デフォルトでは、データ・コントロール・パレットから入力テキスト・コンポーネントとして属性をドロップすると、そのコンポーネントに自動的にaf:validatorタグが追加され、関連するバインディングのvalidatorプロパティにバインドされます。このバインディングにより、クライアント側で処理するADFモデル検証にアクセスできます。詳細は、20.3.2項「データ・コントロール・パレットを使用した入力フィールドの作成時に行われる処理」を参照してください。ADFモデル検証の詳細は、20.3.1.2項「ADFモデル検証の追加」を参照してください。


ADF Facesバリデータを追加する手順:

  1. 構造ウィンドウで、バリデータを追加するコンポーネントを右クリックします。

  2. ポップアップ・メニューで「<UIコンポーネント>の中に挿入」「ADF Faces Core」を選択して、ADF Facesバリデータを挿入します。(JSFの参照実装バリデータを挿入するには、「<UIコンポーネント>の中に挿入」「JSF Core」を選択します。)

  3. バリデータ・タグ(ValidateDateTimeRangeなど)を選択します。

  4. プロパティ・インスペクタで、属性の値(検証エラーのメッセージなど)を設定します。追加のヘルプは、属性を右クリックして「ヘルプ」を選択すると表示されます。

    ADF Facesでは、検証エラー・メッセージの詳細部分をカスタマイズできます。XxxMessageDetail属性の値を設定することで(XxxmaximumMessageDetailなどの検証エラー・タイプ)、検証が失敗したときにデフォルト・メッセージのかわりにカスタム・メッセージを表示できます。

20.3.1.2 ADFモデル検証の追加

エンティティ・オブジェクトのビジネス・ドメイン・レイヤーに検証規則をすでに設定している場合は、ADFモデル検証を追加する必要はありません。ADF Business Componentsアプリケーションでは、アプリケーション・モジュールのデータ・コントロール以外のデータ・コントロールを使用しないかぎり、ADFモデル検証を使用する必要はありません。

表20-4に、属性に対して構成できるADFモデル検証規則を示します。

表20-4 ADFモデル検証規則

バリデータ規則名 説明

比較

属性の値とリテラル値を比較する。

リスト

値が値リスト内にあるかどうかを検証する。

レンジ

値が値範囲内にあるかどうかを検証する。

長さ

値の文字またはバイト・サイズをサイズおよびオペランド(greater than or equal toなど)に対して検証する。

正規表現

Java正規表現構文を使用してデータを検証する。


ADFモデル検証規則を作成する手順:

  1. 規則を作成する属性が含まれるページ定義を開きます。

  2. 構造ウィンドウで、属性、リストまたは表バインディングを選択します。

  3. プロパティ・インスペクタで「検証規則の編集」リンクを選択します。

  4. 検証規則エディタで、属性名を選択し、「新規」をクリックします。

  5. 「検証規則の追加」ダイアログで、検証規則を選択し、それに応じて規則を構成します。様々なタイプの規則を作成する際の追加のヘルプは、「ヘルプ」をクリックすると表示されます。


注意:

ADF Business Componentsの宣言的な検証規則の詳細は、6.7項「宣言的な検証規則の使用」を参照してください。

20.3.2 データ・コントロール・パレットを使用した入力フィールドの作成時に行われる処理

属性をデータ・コントロール・パレットから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になることができるかどうかが評価されます。

20.3.3 実行時に行われる処理

ユーザーがページを送信すると、ADF Facesのvalidate()メソッドにより最初に、送信された値でコンポーネントのrequired属性がtrueかどうかが確認されます。値がnullまたはゼロ長の文字列であった場合、コンポーネントは無効化されます。この時点では、クライアント側の検証が有効になっているかどうかによって実行される処理が異なります。

クライアント側の検証が有効になっている場合、エラー・メッセージがキューに挿入されます。他のバリデータがコンポーネントに登録されている場合、それらのバリデータはコールされず、現在のページが、エラー・メッセージを示すダイアログとともに再表示されます。


注意:

JSFの参照実装バリデータはクライアント側では実行されません。

例20-2では、image属性の値は必須ではありません。ただし、これ以外の値はmandatoryプロパティによって設定されているため、必須です。これは、図20-2に示すように、入力テキスト・フィールドの横にあるアスタリスクによってWebページで示されます。図20-2は、クライアント側検証が有効であり、製品IDのデータが入力されなかった場合に表示されるアラート・ダイアログも示しています。3つの必須フィールドすべてにデータが入力されないと、アラートで3つのエラー・メッセージが表示されます。

図20-2 クライアント側での必須の値のエラー

ポップアップ・ダイアログに表示されるエラー・メッセージ

送信された値がNULL以外の値か、少なくとも1つの文字からなる文字列値であった場合、検証プロセスは続行され、コンポーネントに設定されているすべてのバリデータが1つずつコールされます。コンポーネントのaf:validatorタグはバインディングのvalidatorプロパティにバインドされるため、モデルに設定されている検証ルーチンもこのときにアクセスされて実行されます。

続いて、プロセスは次のコンポーネントに進みます。すべての検証が正常に完了すると、モデル値更新フェーズが開始され、ローカル値を使用してモデルが更新されます。いずれかの検証が失敗すると、現在のページがエラー・ダイアログとともに再表示されます。

クライアント側検証が無効になっている場合は、すべての検証がサーバー側で実行されます。まず、検証処理フェーズでADF Faces検証が実行されます。エラーが発生した場合、値は無効化され、関連付けられたメッセージがFacesContext内のキューに追加されます。コンポーネントに対してすべての検証が実行された後、モデル・レイヤーに制御が渡されます。次に、モデル・レイヤーによってモデル更新検証フェーズが実行されます。検証処理フェーズと同様に、エラーが見つかった場合は値が無効化され、関連付けられたメッセージがFacesContext内のキューに追加されます(検証または変換以外のエラーが処理される方法の詳細は、20.8項「ADFアプリケーション内の例外の処理と表示」を参照してください)。次に、ライフサイクルはレスポンス・レンダリング・フェーズにジャンプし、現在のページが再表示されます。ADF Facesにより自動的に、エラーを生成した入力コンポーネントのラベルの横にエラー・アイコンが表示され、関連付けられたメッセージが入力フィールドの下に表示されます。フィールドにヒントが関連付けられている場合は、ヒントの下にエラー・メッセージが表示されます。図20-3は、サーバー側の検証エラーを示しています。

図20-3 サーバー側の検証エラー

コンポーネントの下にエラー・メッセージが表示されます。

20.3.4 留意事項

1つのコンポーネントに対してrequired属性を設定し、かつバリデータも使用することができます。ただし、required属性をtrueに設定した場合、値がnullまたは長さが0の文字であると、コンポーネントは無効化され、そのコンポーネントに登録されている他のバリデータはコールされません。

コンポーネントが空でも有効になるケースが存在する場合は、この組合せでは問題があることがあります。たとえば、ページに「Cancel」ボタンが含まれている場合、ユーザーはデータを入力しなくても、そのボタンをクリックすればページを閉じることができるようにする必要があります。このようなケースを処理するには、「Cancel」ボタンのコンポーネントのimmediate属性をtrueに設定します。この属性により、リクエスト値の適用フェーズでこのアクションが実行されるため、アクションが実行されるたびに検証が省略されます。

20.4 カスタムJSF検証の作成

この項では、バッキングBeanの検証メソッドを追加する方法と、カスタムJSFバリデータを作成する方法について説明します。Method Validatorを使用してカスタム検証コードをADF Business Componentsで起動する方法や、カスタム・コードを使用して宣言的な規則の基本セットを拡張する方法の詳細は、第9章「エンティティ・オブジェクト内のプログラム的なビジネス・ルールの実装」を参照してください。

カスタム検証ロジックは、単一ページ上のコンポーネントに必要な場合があります。たとえば、日付を入力する個別の入力フィールド(月、日、年フィールド)それぞれが独自のバリデータを持つ場合は、ユーザーが「February 30, 2005」と入力してもエラーは表示されません。このような場合は、検証メソッドをページのバッキングBeanに作成することで、検証でページ上の個別のコンポーネントにアクセスし、日付全体を検証できるようになります。

アプリケーション内部の複数のページで再使用されるカスタム検証ロジックが必要な場合や、クライアント側で検証が実行されるようにする場合は、JSFバリデータ・クラスを実装する必要があります。その後でADF Facesバージョンを作成すれば、クライアント側でバリデータが実行されます。

再使用可能なカスタム検証規則を実装してドメイン・ビジネス・レイヤーの一部として使用する場合は、26.9項「カスタム検証規則の実装」を参照してください。

20.4.1 バッキングBeanの検証メソッドの作成方法

1つのページ上のコンポーネントに対してカスタム検証が必要な場合は、必要な検証を提供するメソッドをバッキングBean上に作成できます。

バッキングBeanの検証メソッドを追加する手順:

  1. 検証が必要となるコンポーネントをJSFページに挿入します。

  2. ビジュアル・エディタで、コンポーネントをダブルクリックして「バインドvalidatorプロパティ」ダイアログを起動します。

  3. 「バインドvalidatorプロパティ」ダイアログで、検証メソッドを収容するマネージドBeanを入力または選択するか、「新規」をクリックして新しいマネージドBeanを作成します。ロジックがすでに存在する場合は、提供されたデフォルトのメソッド・シグネチャを使用するか、既存のメソッドを選択します。

    ダイアログで「OK」をクリックすると、JDeveloperによりスケルトン・メソッドがコードに追加され、ソース・エディタ内にBeanが開きます。

  4. 必要な検証ロジックを追加します。このロジックには、適切な例外をスローするためのjavax.faces.validator.ValidatorException と、対応するエラー・メッセージを生成するためのjavax.faces.application.FacesMessageを使用する必要があります。ValidatorインタフェースおよびFacesMessageの詳細は、javax.faces.validator.Validatorおよびjavax.faces.application.FacesMessageのJavadocを参照するか、http://java.sun.com/にアクセスしてください。

20.4.2 バッキングBeanの検証メソッドを作成するときに行われる処理

検証メソッドを作成すると、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属性がバインドされたメソッドが実行されます。

20.4.3 カスタムJSFバリデータの作成方法

カスタム・バリデータを作成するには、検証のビジネス・ロジックを記述する必要があります。これには、Validatorインタフェースのvalidateメソッドをオーバーライドするメソッドを含むValidator実装を作成してから、カスタム・バリデータをアプリケーションに登録します。また、バリデータのタグを作成したり、af:validatorタグを使用してカスタム・バリデータをそのタグのプロパティとしてネストすることもできます。

その後、クライアント側バージョンのバリデータを作成できます。ADF Facesのクライアント側検証は、サーバー側の標準的な検証と同じように機能します。ただし、クライアント側ではJavaScriptが使用されます。これは、JavaScriptのバリデータ・オブジェクトではValidatorExceptionsをスローでき、validate()メソッドをサポートしているためです。


注意:

JavaScript form.submit()関数がコールされた場合、ADF Facesのクライアント側検証のサポートは省略されます。ADF Facesでは、かわりに使用できるsubmitForm()メソッドが用意されています。あるいは、ADF Faces入力コンポーネントのautoSubmit属性を使用することもできます。

カスタムJSFバリデータを作成する手順:

  1. 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/にアクセスしてください。

  2. 必要な検証ロジックを追加します。このロジックには、適切な例外をスローするためのjavax.faces.validator.ValidatorException と、対応するエラー・メッセージを生成するためのjavax.faces.application.FacesMessageを使用する必要があります。ValidatorインタフェースおよびFacesMessageの詳細は、javax.faces.validator.Validatorおよびjavax.faces.application.FacesMessageのJavadocを参照するか、http://java.sun.com/にアクセスしてください。


    注意:

    ページ作成者がそのページから属性を構成できるようにするには、バリデータのタグを作成する必要があります。詳細は、手順5を参照してください。ページ上に属性を構成しない場合は、この実装クラス内に属性を構成する必要があります。

  3. アプリケーションでクライアント側の状態を保存する場合は、カスタム・バリデータ実装にSerializableインタフェースを実装するか、StateHolderインタフェースとStateHoldersaveState(FacesContext)メソッドおよびrestoreState(FacesContext, Object)メソッドを実装します。詳細は、javax.faces.componentパッケージのStateHolderインタフェースのJavadocを参照してください。

  4. faces-config.xmlファイル内でバリデータを登録します。

    • faces-config.xmlファイルを開き、エディタ・ウィンドウ内で「概要」タブを選択します。faces-config.xmlファイルは<View_Project>/WEB-INFディレクトリ内にあります。

    • ウィンドウ内で「バリデータ」を選択し、「新規」をクリックします。「ヘルプ」をクリックするか、[F1]を押すと、バリデータの登録に関する追加のヘルプが表示されます。

  5. オプションで、クラスの属性を設定するバリデータのタグを作成します。タグを作成するには、アプリケーションのタグ・ライブラリ定義ファイル(TLD)内にタグのエントリを追加します。この手順は次のとおりです。

    • アプリケーションのTLDを開くか、作成します。TLDの作成方法の詳細は、http://java.sun.com/にアクセスしてください。

    • faces-config.xmlファイル内に登録されているバリデータIDとクラスを定義します。

    • その構成ファイル内に登録されているプロパティまたは属性を定義します。


    注意:

    バリデータのタグを作成しない場合は、Validator実装内に属性を構成する必要があります。

クライアント側バージョンのバリデータを作成する手順:

  1. JavaScriptバージョンのバリデータを作成し、関連する情報をコンストラクタに渡します。

  2. 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ページでカスタム・バリデータを使用する手順:

  • 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をネストする必要があります。

  1. 構造ウィンドウから、検証を追加する入力コンポーネントを右クリックし、「<コンポーネント>の中に挿入」「ADF Faces Core」「バリデータ」を選択します。

  2. ドロップダウン・リストからバリデータのIDを選択し、「OK」をクリックします。

    JDeveloperにより、バリデータIDをvalidatorタグのプロパティにするコードがJSFページに挿入されます。

例20-6に、JSFページでのaf:validatorタグを使用するバリデータのコードを示します。

例20-6 JSFページ上のコンポーネントにネストされたカスタム・バリデータ

<af:inputText id="empnumber" required="true">
  <af:validator validatorID="emValidator"/>
</af:inputText>

20.4.4 カスタムJSFバリデータを使用するときに行われる処理

カスタムJSFバリデータを使用すると、アプリケーションは、カスタム・タグまたはaf:validatorタグ内で参照されているバリデータ・クラスにアクセスし、validateメソッドを実行します。このメソッドは、現在のFacesContext内のコンポーネントからデータにアクセスし、そのデータに対してロジックを実行してデータが有効かどうかを判断します。バリデータが属性を持つ場合、それらの属性もアクセスされ、検証ルーチンで使用されます。標準的なバリデータと同様に、カスタム検証が失敗した場合は、関連付けられたメッセージがFacesContext内のメッセージ・キューに挿入されます。

20.5 変換の追加

Webアプリケーションは、モデル・レイヤー内に多くのタイプのデータ(intlongdateなど)を格納できます。ただし、クライアント・ブラウザで表示されるとき、ユーザー・インタフェースには、ユーザーが読取りまたは変更できるような形式でデータが表示される必要があります。たとえば、フォーム内の「date」フィールドでは、java.util.Dateオブジェクトがmm/dd/yyyyという書式パターンのテキスト文字列として表示されるようにします。ユーザーが「date」フィールドを編集してフォームを送信した場合、文字列は、アプリケーションで要求されるタイプに変換される必要があります。変換後のデータは、規則および条件に対して検証されます。

コンバータが存在するタイプの属性をドロップしてinputTextコンポーネントを作成すると、JDeveloperにより、そのコンバータのタグが入力コンポーネントの子として自動的に追加されます。このタグによりコンバータが起動され、ユーザーが入力したStringは、オブジェクトにより期待されるタイプに再び変換されます。

JSF標準コンバータは、Strings型と単純なデータ型の間の変換を扱い、javax.faces.convert.Converterインタフェースを実装します。次のJSF標準コンバータ・クラスが提供されています。

表20-5に、ADF Facesにより提供されるコンバータを示します。

表20-5 ADF Facesのコンバータ

コンバータ タグ名 説明

ColorConverter

af:convertColor

java.lang.Stringオブジェクトをjava.awt.Colorオブジェクトに変換する。カラー・パターンのセットはコンバータの属性として指定する。

DateTimeConverter

af:convertDateTime

java.lang.Stringオブジェクトをjava.util.Dateオブジェクトに変換する。日付のパターンとスタイルは、コンバータの属性として指定する。

NumberConverter

af:convertNumber

java.lang.Stringオブジェクトをjava.lang.Numberオブジェクトに変換する。数値のパターンとタイプは、コンバータの属性として指定する。


バリデータの場合と同様に、ADF Facesコンバータも、adf-faces-config.xmlファイル内でクライアント側検証が明示的に無効化されていないかぎり、クライアント側で実行されます。


注意:

JSFの参照実装コンバータはクライアント側では実行されません。

ADF Facesでは、色、日付および数値に対するJavaScript対応コンバータだけでなく、次のいずれかのJavaタイプにバインドされる入力テキスト・フィールドに対するJavaScript対応コンバータも提供されます。

表20-5にリストされているコンバータとは異なり、JavaScript対応コンバータは、必要な場合に自動的に使用されます。これらのコンバータには、コンポーネント内にネストできるタグは関連付けられていません。

20.5.1 コンバータの使用方法

ADF Facesコンバータが存在する属性をデータ・コントロール・パレットからドロップすると、JDeveloperにより、自動的にそのコンバータが入力コンポーネントに追加されます。手動でコンバータを挿入することもできます。

タグを持つADF Facesコンバータを追加する手順:

  1. 構造ウィンドウで、コンバータを追加するコンポーネントを右クリックします。

  2. ポップアップ・メニューで「<UIコンポーネント>の中に挿入」「ADF Faces Core」を選択してADF Facesコンバータを挿入するか、「JSF Core」を選択してJSFコンバータを挿入します。

  3. コンバータ・タグ(ConvertDateTimeなど)を選択します。

  4. プロパティ・インスペクタで、属性の値(変換エラーのメッセージなど)を設定します。追加のヘルプは、属性を右クリックして「ヘルプ」を選択すると表示されます。

    ADF Facesでは、変換エラー・メッセージの詳細部分をカスタマイズできます。XxxMessageDetail属性の値を設定することで(XxxconvertDateMessageDetailなどの変換エラー・タイプ)、変換が失敗したときにデフォルト・メッセージのかわりにカスタム・メッセージを表示できます。

20.5.2 データ・コントロール・パレットを使用した入力フィールドの作成時に行われる処理

データ・コントロール・パレットを使用して、コンバータでサポートされているタイプの入力フィールドを作成すると、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項「トリガーによってデータベース順序から割り当てられた主キー値」を参照してください。

20.5.3 実行時に行われる処理

コンバータが含まれたページをユーザーが送信すると、ADF Facesのvalidate()メソッドによりコンバータのgetAsObject()メソッドがコールされ、文字列値が必要なオブジェクト・タイプに変換されます。コンバータがアタッチされておらず、コンポーネントがモデル内のbeanプロパティにバインドされている場合、JSFでは自動的に、beanプロパティと同じデータ型を持つコンバータが使用されます。変換が失敗した場合、送信された値に無効のマークが付けられ、JSFにより、FacesContextで保持されているキューにエラー・メッセージが追加されます。変換が正常に完了し、コンポーネントにアタッチされているバリデータがない場合、変換された値はローカル値として格納され、後でモデルの更新に使用されます。

20.6 カスタムJSFコンバータの作成

特定のビジネス・ニーズに合せて、独自のコンバータを作成できます。カスタムJSFバリデータを作成する場合と同様に、サーバー側で実行されるカスタムJSFコンバータを作成してから、クライアント側で実行できるJavaScriptバージョンを作成できます。ただし、カスタム・バリデータを作成する場合とは異なり、作成できるのはコンバータ・クラスのみです。変換を提供するためにメソッドをバッキングBeanに追加することはできません。

20.6.1 カスタムJSFコンバータの作成方法

カスタム・コンバータを作成するには、変換のビジネス・ロジックを記述する必要があります。これには、ConverterインタフェースのgetAsObjectおよびgetAsStringメソッドをオーバーライドするメソッドを含むConverterインタフェースの実装を作成してから、カスタム・コンバータをアプリケーションに登録します。次にf:converterタグを使用し、そのタグのプロパティとしてカスタム・コンバータをネストします。あるいは、そのコンバータにバインドする入力コンポーネントのconverter属性を使用することもできます。

また、クライアント側バージョンをコンバータを作成することもできます。ADF Facesのクライアント側コンバータは、サーバー側の標準的なJSF変換と同じように機能します。ただし、クライアント側ではJavaScriptが使用されます。これは、JavaScriptのコンバータ・オブジェクトではConverterExceptionsをスローでき、getAsObjectメソッドおよびgetAsStringメソッドをサポートしているためです。


注意:

JavaScript form.submit()関数がコールされた場合、ADF Facesのクライアント側変換のサポートは省略されます。ADF Facesでは、かわりに使用できるsubmitForm()メソッドが用意されています。あるいは、ADF Faces入力コンポーネントのautoSubmit属性を使用することもできます。

カスタムJSFコンバータを作成する手順:

  1. 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/にアクセスしてください。

  2. 必要な変換ロジックを追加します。このロジックには、適切な例外をスローするためのjavax.faces.converter.ConverterException と、対応するエラー・メッセージを生成するためのjavax.faces.application.FacesMessageを使用する必要があります。ConverterインタフェースおよびFacesMessageの詳細は、javax.faces.converter.Converterおよびjavax.faces.application.FacesMessageのJavadocを参照するか、http://java.sun.com/にアクセスしてください。

  3. アプリケーションでクライアント側の状態を保存する場合は、カスタム・コンバータ実装でSerializableインタフェースを実装するか、StateHolderインタフェースと、StateHoldersaveState(FacesContext)メソッドおよびrestoreState(FacesContext, Object)メソッドを実装します。詳細は、javax.faces.componentパッケージのStateHolderインタフェースのJavadocを参照してください。

  4. faces-config.xmlファイル内でコンバータを登録します。

    • faces-config.xmlファイルを開き、エディタ・ウィンドウ内で「概要」タブを選択します。faces-config.xmlファイルは<View_Project>/WEB-INFディレクトリ内にあります。

    • ウィンドウ内で「コンバータ」を選択し、「新規」をクリックします。「ヘルプ」をクリックするか、[F1]を押すと、コンバータの登録に関する追加のヘルプが表示されます。

クライアント側バージョンのコンバータを作成する手順:

  1. JavaScriptバージョンのコンバータを作成し、関連する情報をコンストラクタに渡します。

  2. 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}"/>

ここで、myPropertyの型はカスタム・コンバータと同じです。


20.6.2 カスタム・コンバータを使用するときに行われる処理

カスタム・コンバータを使用すると、アプリケーションは、converter属性内で参照されているコンバータ・クラスにアクセスし、適宜getAsObjectまたはgetAsStringメソッドを実行します。これらのメソッドは、現在のFacesContext内のコンポーネントからデータにアクセスし、変換ロジックを実行します。

20.7 エラー・メッセージの表示

デフォルトでは、ADF Facesの検証と変換はクライアント側で実行されます。1つのコンポーネントのデータ検証が失敗すると、そのコンポーネントのエラー・メッセージが示されたアラート・ダイアログが表示されます。クライアント側のエラー・メッセージをこのように表示するために、追加の作業を行う必要はありません。図20-4は、required属性がtrueに設定された入力コンポーネントに対してデータが入力されなかった場合に表示されるメッセージを示しています。

図20-4 クライアント側のエラー・メッセージ

エラー・メッセージがポップアップ・ダイアログ内に表示されます。

ADF Facesでは、検証または変換が失敗したときに表示されるメッセージのデフォルト・テキストが用意されています。デフォルトのメッセージを独自のメッセージで置き換えるには、バリデータまたはコンバータのxxxMessageDetail属性(convertDateMessageDetailnotInRangeDetailMessageなど)のテキストを設定するか、EL式を使用してこれらの属性をリソース・バンドルにバインドします。リソース・バンドルの使用方法の詳細は、22.4.1項「アプリケーションを国際化する方法」を参照してください。

データ・コントロール・パレットを使用して入力コンポーネントを作成すると、JDeveloperによりページの最上部にaf:messagesタグが挿入されます。このタグにより、サーバー側で行われた検証に対するキュー内のすべてのエラー・メッセージを、色でオフセットされたボックス内に表示できます。ADF Facesのクライアント側検証を無効にするように選択した場合、これらのエラー・メッセージがADFモデルのエラー・メッセージとともに表示されます。ADFモデルのメッセージが最初に表示されます。メッセージは、af:messagesタグ内と、関連付けられたコンポーネントの傍に表示されます。

図20-5は、ADFモデルの検証規則に対する、説明が長すぎるというエラー・メッセージを示しています。同時に、ADF Facesコンポーネントのrequired属性の違反に対するエラー・メッセージも表示されています。

図20-5 ADF Facesのmessageタグを使用したサーバー側エラー・メッセージの表示

メッセージがページの最上部とコンポーネントの下に表示されます。

20.7.1 ページ上にサーバー側エラー・メッセージを表示する方法

af:messagesタグを使用して、ページ最上部のボックス内にサーバー側のエラー・メッセージを表示できます。データ・コントロール・パレットから入力コンポーネントとしての項目をページ上にドロップすると、JDeveloperにより自動的にこのタグが追加されます。

エラー・ボックス内にエラー・メッセージを表示する手順:

  1. 構造ウィンドウでaf:messagesタグを選択します。

    このタグは、データ・コントロール・パレットから入力ウィジェットをドロップすると自動的に作成されます。ただし、タグの挿入が必要な場合は、次のコードをafh:bodyタグに挿入します。

    <afh:body>
      <af:messages globalOnly="false" />
      ...
    </afh:body>
    
  2. プロパティ・インスペクタで次の属性を設定します。

    • globalOnly: デフォルトでは、ADF Facesによってグローバル・メッセージ(コンポーネントに関連付けられていないメッセージ)が表示され、続いて個別のコンポーネント・メッセージが表示されます。ボックス内にグローバル・メッセージのみを表示する場合は、属性をtrueに設定します。その場合も、関連付けられたコンポーネントの傍にコンポーネント・メッセージが表示されます。

    • message: メッセージ・ボックス・タイトルのすぐ下、個別メッセージのリストの上に表示されるメイン・メッセージ・テキスト。

    • text: メッセージ・ボックスのデフォルトのタイトルをオーバーライドするテキスト。

  3. クライアント側の検証が無効になっていることを確認します。クライアント側の検証を無効化していない場合、サーバー側の検証は実行されないため、アラート・ダイアログにADF Faces検証エラーがあるかどうかが表示されます。


    ヒント:

    クライアント側検証を無効化するには、adf-faces-config.xml内に<client-validation-disabled>要素を追加し、それをtrueに設定します。

20.7.2 エラー・メッセージの表示を選択するときに行われる処理

ADF Faces入力コンポーネントの変換または検証エラーが発生すると、コンポーネントはFacesMessageオブジェクトを作成し、FacesContextインスタンスのメッセージ・キューにそれを追加します。レスポンスのレンダリング・フェーズで、ADF Faces入力コンポーネントの組込みメッセージ表示属性を使用して、バリデータまたはコンバータに関連付けられたメッセージが表示されます。この属性により、コンポーネントの横に詳細なエラー・メッセージが表示されます。メッセージはオプションのaf:messagesタグによっても表示されます。このタグを使用すると、メッセージ・ボックス内にすべてのサマリー・メッセージが表示されます。

20.8 ADFアプリケーション内の例外の処理と表示

ADFアプリケーションの一部によりスローされた例外も、JSFページ上で処理および表示されます。デフォルトでは、アプリケーション内でスローされた例外はすべてバインディング・コンテナにより捕捉されます。例外が発生すると、バインディング・コンテナは例外をアプリケーションのアクティブなエラー・ハンドラ(デフォルトではDCErrorHandlerImplクラス)にルーティングします。このクラスのReportException(BindingContainer, Exception)メソッドは、例外を処理のためにバインディング・コンテナに渡します。バインディング・コンテナは、その例外をキャッシュ内の例外リストに挿入することにより処理します。ページ・ライフサイクル中(たとえば、検証中)にページ上に例外が発生すると、それらの例外もバインディング・コンテナにより捕捉されてキャッシュされ、FacesContextに追加されます。

レンダリングの準備フェーズで、ADFライフサイクルはreportErrors(context)メソッドを実行します。このメソッドの実装の方法は、表示テクノロジごとに異なります。デフォルトでは、FacesPageLifecycleクラスのreportErrorsメソッドが次の処理を実行します。

このデフォルトのフレームワークの動作は、カスタマイズできます。たとえば、例外のカスタム・エラー・ハンドラを作成したり、ライフサイクルで例外がレポートされる方法を変更できます。また、1つのページで例外が処理される方法をカスタマイズすることもできます。

20.8.1 例外処理の変更方法

デフォルトの例外処理を変更するには、デフォルトのエラー・ハンドラ(DCErrorHandlerImpl)を拡張します。また、モデル準備フェーズで新しいエラー・ハンドラをコールするカスタムADFライフサイクル・クラスを作成する必要もあります。

また、カスタムADFライフサイクル・クラスを作成して、reportErrorsメソッドをオーバーライドすることにより、ライフサイクルでエラーがレポートされる方法を変更することもできます。

1つのページに対して例外が作成される方法を変更するのみの場合は、そのページにのみライフサイクル・クラスを作成できます。

カスタム・エラー・ハンドラを作成する手順:

  1. DCErrorHandlerImplクラスを拡張するクラスを作成します。

  2. 新規のクラスで、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]);
            }
          }
        }
      }
    }
    
  3. エラー・ハンドラをグローバルにオーバーライドします。これには、FacesPageLifecycleを拡張するカスタム・ページ・ライフサイクル・クラスを作成する必要があります。このクラス内で、エラー・ハンドラを設定するpublic void prepareModel(LifecycleContext)メソッドをオーバーライドします。エラー・ハンドラをカスタム・ハンドラに設定するには、メソッドを使用して、カスタム・エラー・ハンドラがバインディング・コンテキスト内で現行エラー・ハンドラになっているかどうかを確認します。現行エラー・ハンドラになっていない場合は、現行エラー・ハンドラに設定します。(デフォルトでは、ADFBindingFilterは常にエラー・ハンドラをDCErrorHandlerImplに設定するため、メソッドによりそれをカスタム・エラー・ハンドラに戻す必要があります。)次にsuper.prepareModelをコールする必要があります。

    例20-10に、FacesPageLifecycleクラスを拡張するframeworkExt.SRDemoPageLifecycleクラスからのprepareModelメソッドを示します。このメソッドは、エラー・ハンドラがSRDemoErrorHandlerのインスタンスであるかどうかを確認し、そうでない場合にはエラー・ハンドラを新規のエラー・ハンドラに設定することに注意してください。

    例20-10 prepareModelメソッド

    public void prepareModel(LifecycleContext ctx) {
        if (!(ctx.getBindingContext().getErrorHandler() instanceof
              SRDemoErrorHandler)) {
            ctx.getBindingContext().setErrorHandler(new SRDemoErrorHandler(true));
        }
        //etc
        super.prepareModel(ctx);
    }
    
  4. 今度は、カスタム・ライフサイクルを返す新規のフェーズ・リスナーを作成する必要があります。手順については、この後の「新規のフェーズ・リスナーを作成する手順:」を参照してください。

ライフサイクルでエラーがレポートされる方法をカスタマイズする手順:

  1. FacesPageLifecycleを拡張するカスタム・ページ・ライフサイクル・クラスを作成します。

  2. public void reportErrors(PageLifecycleContext)メソッドをオーバーライドして、エラー・メッセージの表示をカスタマイズします。

    SRDemoでreportErrors()メソッドを確認します。このメソッドは、frameworkExt.SRDemoPageLifecycleクラスにあります。このメソッドでは、ユーザーが直接修正できないリストから例外を削除することで、エラー処理をカスタマイズします。一般に、削除されるエラーは、ADF Business Componentsのバンドル例外モードで追加されるラッパー例外です。バンドル例外モードの詳細は、10.5.7項「バンドル例外モードの理解」を参照してください。

  3. 今度は、カスタム・ライフサイクルを返す新規のフェーズ・リスナーを作成する必要があります。

新規のフェーズ・リスナーを作成する手順:

  1. ADFPhaseListenerクラスを拡張します。

  2. protected PageLifecycle createPageLifecycle ()メソッドをオーバーライドして、新規のカスタム・ライフサイクルを戻します。

    例20-11に、frameworkExt.SRDemoADFPhaseListenerクラス内のcreatePageLifecycleメソッドを示します。

    例20-11 SRDemoADFPhaseListener内のcreatePageLifecycleメソッド

    public class SRDemoADFPhaseListener extends ADFPhaseListener {
      protected PageLifecycle createPageLifecycle() {
        return new SRDemoPageLifecycle();
      }
    }
    
  3. faces-config.xmlファイル内でフェーズ・リスナーを登録します。

    • faces-config.xmlファイルを開き、エディタ・ウィンドウ内で「概要」タブを選択します。faces-config.xmlファイルは<View_Project>/WEB-INFディレクトリ内にあります。

    • ウィンドウ内で「ライフ・サイクル」を選択し、「新規」をクリックします。「ヘルプ」をクリックするか、[F1]を押すと、フェーズ・リスナーの登録に関する追加のヘルプが表示されます。

1つのページの例外処理をオーバーライドする手順:

  1. FacesPageLifecycleクラスを拡張するカスタム・ページ・ライフサイクルを作成します。

  2. public void reportErrors(PageLifecycleContext)メソッドをオーバーライドして、エラー・メッセージの表示をカスタマイズします。このメソッドのオーバーライドの例は、前述の「ライフサイクルでエラーがレポートされる方法をカスタマイズする手順:」を参照してください。

  3. ページのページ定義を開きます。構造ウィンドウで、ページ定義ノードを選択します。プロパティ・インスペクタで、ControllerClass属性の値として新規のクラスを入力します。

20.8.2 デフォルトのエラー処理を変更するときに行われる処理

独自のエラー・ハンドラを作成すると、アプリケーションではDCErrorHandlerクラスではなくそのクラスが使用されます。新規のライフサイクルを作成して登録したため、そのライフサイクルがアプリケーションに使用されます。この新規のライフサイクルによって、カスタム・エラー・ハンドラがインスタンス化されます。

以降にエラーが見つかると、バインディング・コンテナがエラーをカスタム・エラー・ハンドラにルーティングします。次に、reportException(BindingContainer, Exception)メソッドが実行されます。

カスタム・ライフサイクル・クラス内のreportErrorsメソッドをオーバーライドした場合は、レンダリング準備フェーズでライフサイクルによって新規のreportErrors(context)メソッドが実行されます。