ヘッダーをスキップ
Oracle® Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド
11g リリース2(11.1.2.2.0)
B69399-01
  目次へ移動
目次

前
 
次
 

16 ADFモデル・レイヤーでの検証の使用

この章では、Oracle Application Development Framework (Oracle ADF)アプリケーションのADFモデル・レイヤーで検証規則を作成し、ユーザー・インタフェースに入力されるデータがビジネス・サービス・レイヤーではなくページで検証されるようにする方法を説明します。

この章は次の項で構成されています:

16.1 ADFモデル・レイヤー検証について

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

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

16.1.1 ADFモデル・レイヤー検証のユースケースと例

アプリケーションでADF Business Componentsに基づかないデータ・コントロールを使用している場合は、ADFモデル・レイヤー検証を使用してユーザーが入力したデータの品質を確保できます。


ベスト・プラクティス:

可能な場合はビジネス・レイヤー検証を使用します。ただし、次の例に示すような場合には、モデル・レイヤー検証の使用が必要になる場合があります。

  • ビジネス・レイヤーが宣言的検証をサポートしていない場合。

  • 負荷の高いラウンドトリップ(Webサービスとのバインドなど)が開始される前に検証を実行する場合。

  • パラメータを使用して作成されたフォームを検証する必要がある場合(executeWithParams操作を使用する場合など)。

また、サーバーとのラウンドトリップの前に検証を実行する場合、クライアント側の検証を使用することもできます。『Oracle Fusion Middleware Oracle Application Development Framework Webユーザー・インタフェース開発者ガイド』の検証の追加に関する項を参照してください。


アプリケーションで、ビジネス・レイヤー検証に加えてモデル・レイヤー検証の使用も保証されている場合は、ADF Business Componentsオブジェクトで利用できる宣言的検証機能の多くをモデル・レイヤーでも利用できます。

16.1.2 ADFモデル・レイヤー検証の追加機能

モデル・レイヤー認証を使用する前に、他のADF検証機能を理解しておくと役立つ場合があります。次に、関連する他の機能へのリンクを示します。

  • ADF Business Componentsアプリケーション・モジュールのデータ・コントロールを使用する場合、モデル・レイヤー検証を使用する必要はありません。可能であれば、すべての検証規則を、ビジネス・レイヤー内の再使用と管理が容易で一元管理されたエンティティ・オブジェクトに定義することを検討してください。詳細は、第7章「検証とビジネス・ルールの宣言的な定義」を参照してください。

  • ページ・レベルで利用できる宣言的検証機能の多くは、Beanレベルでも利用できます(その場合はデータ・コントロール構造ファイルで実装します)。データ・コントロール構造ファイルの検証規則は、データ・コントロールが使用されるすべての場合に適用されるため、非常に役立ちます。データ・コントロール構成ファイルで検証規則を実装する場合の詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Java EE開発者ガイド』の「データ・コントロールへのビジネス・ロジックの追加」を参照してください。

16.2 ADFモデル・レイヤーでの検証規則の定義

バインディングの属性に対するADFモデル検証は、ページ定義ファイルで構成できます。モデル・レイヤーの検証規則は、特定のページのバインディング属性に対して、その対象を含むフォームの送信時に実行されます。

オプションで、skipValidationプロパティをtrueに設定すると、ADFモデル検証をバイパスできます。skipValidationskipDataControlsに設定して、トランザクションを検証せずに、バインド・オブジェクトを検証できます。たとえば、データ入力を受け付けるポップアップ・ウィンドウを開く表アクションがあるときに、表でコミットする前にビュー・レイヤーでこれらの入力を検証できるようにする場合は、skipValidationskipDataControlsに設定します。構造ウィンドウでページ定義ファイルのルート・ノードを選択すると、skipValidationプロパティがプロパティ・インスペクタに表示されます。

16.2.1 検証の追加方法

ADF Model検証をページ定義ファイルに設定します。検証規則を定義し、規則に違反した場合に表示するエラー・メッセージを設定します。

表16-1に、バインディングの属性に対して構成できるADF Model検証規則を示します。

表16-1 ADF Model検証規則

バリデータ規則名 説明

比較

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

リスト

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

範囲

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

長さ

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

正規表現

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

必須

属性にその値が存在するかどうかを検証する。


作業を始める前に、次のようにします。

モデル・レイヤーでの検証規則の使用に関する知識があると役立つ場合があります。詳細は、16.2項「ADFモデル・レイヤーでの検証規則の定義」を参照してください。

また、他の検証機能を使用して追加できる機能についても理解しておくと役立ちます。詳細は、16.1.2項「ADFモデル・レイヤー検証の追加機能」を参照してください。

次のタスクを完了する必要があります。

  • ページにコンポーネントを作成します。このコンポーネントにはバインディング属性が必要です。

ADF Model検証規則を作成する手順:

  1. 規則を作成するバインディングが含まれるページ定義を開きます。

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

  3. プロパティ・インスペクタで、「詳細」に続いて「検証ルールの編集」を選択します。

  4. 「検証ルールの編集」ダイアログで「バインディング」ノードを展開し、属性名を選択して、「新規」をクリックします。

  5. 「検証ルールの追加」ダイアログで、検証規則を選択し、必要に応じて規則を構成します。

  6. 「失敗処理」タブを選択して、規則に違反した場合に表示するメッセージを構成します。

16.2.2 実行時に行われる処理: Model検証規則

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

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

16.3 エラー処理のカスタマイズ

デフォルトのDCErrorHandlerImplクラスを拡張するカスタム・エラー・ハンドラを使用して、エラーをレポートできます。カスタム例外ハンドラ・クラスを登録するためにコードを記述する必要はありません。かわりに、構造ウィンドウでDataBindings.cpxファイルのルート・ノードを選択した後、プロパティ・インスペクタを使用してErrorHandlerClassプロパティに、使用するエラー・ハンドラの完全修飾名を設定します。

カスタム・エラー・ハンドラには、次の上書き可能なメソッドを含めることができます。

例16-1は、DCErrorHandlerImplクラスを拡張したカスタム・エラー・ハンドラです。この例は、ユーザーに表示されるリストに載せない例外をスキップするために必要なskipException()メソッドに対するオーバーライドを示しています。

例16-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() {
     this(true);
   }

   public CustomErrorHandler(boolean setToThrow) {
     super(setToThrow); 
     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()に変更する必要があります。例外エラー・ハンドラには、例16-2に示すように、デフォルトのコンストラクタが必要です。

例16-2 デフォルトのコンストラクタ

ErrorHandlerClass="viewcontroller.MyErrorHandler" public MyErrorHandler() {   super(true); }

16.3.1 メッセージの詳細部分のカスタマイズ方法

メッセージの詳細部分をカスタマイズし、使用する予定のある場合は、このメッセージを取得し、処理するために、カスタム・エラー・ハンドラを作成し、getDetailedDisplayMessageメソッドを実装することができます。最終的なメッセージは、ビュー・レイヤーに渡され、他のメッセージと統合されます。

メッセージの詳細部分をカスタマイズするには:

  1. デフォルトのDCErrorHandlerImplクラスを拡張するカスタム・エラー・ハンドラを作成します。

  2. このクラスで、DCErrorMessageオブジェクトを戻すgetDetailedDisplayMessageメソッドをオーバーライドします。

    例16-3に、カスタム・エラー・ハンドラ・クラスでのgetDetailedDisplayMessageメソッドの実装を示します。

    例16-3 getDetailDisplayMessageメソッドを使ったカスタム・エラー・ハンドラ・クラス

    public final class MyErrorMessageHandler extends DCErrorHandlerImpl {
        public MyErrorMessageHandler (){
            super(false);
        }
        public DCErrorMessage getDetailedDisplayMessage(BindingContext ctx,
                                                        RegionBinding ctr,
                                                        Exception ex) {
            ...
            return new MyDCErrorMesssage(ctr, ex);
        }
    }
    
  3. DCErrorMessageインタフェースを実装するカスタム・クラスを作成します。このクラスはgetHTMLTextメソッドおよびgetTextメソッドを実装する必要があります。

    getHTMLTextメソッドに、実際の処理を実行するためのコードを追加しますが、インタフェースの要件を満たすには、getTextの実装も必要です。

  4. getHTMLTextの実装では、エラー・メッセージを作成、処理するためのコードを追加します。

    getDetailedDisplayMessagegetHTMLTextは、エラー・メッセージの最終版をHTMLフラグメントとして戻す必要があります。このフラグメントは、ページのHTMLコードに挿入されます。このため、getDetailedDisplayMessageによりメッセージが戻される前に、テキスト・メッセージに対して、必要な前処理をすべて実行しておく必要があります。たとえば、ローカライズしたメッセージの取得や、メッセージの順番を右から左に変更するなどの処理が必要である場合は、メッセージが戻される前に行います。

    例16-4はこのインタフェースの実装を示しています。

    例16-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 "<b>error</b> message details";
        }
    }
    

16.3.2 複数スレッドを処理するエラー・ハンドラの記述方法

Oracle ADFでは、作成されるBindingContextオブジェクトごとにカスタム・エラー・ハンドラのインスタンスを1つ作成します。Oracle ADFでは、同じ論理エンド・ユーザー・セッションからの同時Webリクエストをシリアライズするため、通常、複数スレッドは同じエラー・ハンドラを同時に使用しません。しかし、スレッドセーフのカスタム・エラー・ハンドラを保証するには、JboExceptionsetProperty() APIを使用します。このメソッドは、表示用に例外がJSF FacesMessageオブジェクトに変換されるときに、後で必要になる可能性があるヒントをすべて例外オブジェクト自体に格納します。