プライマリ・コンテンツに移動
Oracle® Fusion Middleware Oracle Application Development FrameworkによるFusion Webアプリケーションの開発
12c (12.2.1.3.0)
E90376-03
目次へ移動
目次

前
次

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

この章では、Oracle ADFアプリケーションのADFモデル・レイヤー内で検証ルールを使用する方法について説明します。

この章の構成は、次のとおりです。

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

ADFでは、アプリケーションでADFビジネス・コンポーネントに基づかないデータ・コントロールを使用する場合、ユーザーが入力したデータが必ず検証されるように、検証ルールを使用する必要があります。

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

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

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

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

ベスト・プラクティス:

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

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

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

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

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

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

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

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

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

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

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

ADFでは、ページ定義ファイルのバインディング属性を検証するために使用できる検証ルールのリストが提供されています。「検証ルール・エディタ」ダイアログを使用して、属性の検証ルールを追加、編集または削除できます。

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

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

19.2.1 ADFモデル・レイヤー検証の追加方法

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

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

表19-1 ADFモデル検証規則

バリデータ・ルール名 説明

比較

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

リスト

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

範囲

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

長さ

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

正規表現

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

必須

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

始める前に:

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

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

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

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

ADFモデル検証規則を作成するには:

  1. 「アプリケーション」ウィンドウで、ルールを作成するバインディングを含むページ定義をダブルクリックします。
  2. 「構造」ウィンドウで、属性、リストまたは表バインディングを選択します。
  3. 「プロパティ」ウィンドウで、「詳細」ドロップダウン・メニューをクリックし、「検証ルールの編集」を選択します。
  4. 「検証ルール・エディタ」ダイアログで、バインディング・ノードを開き、属性名を選択して、「新規」をクリックします。
  5. 「検証ルールの追加」ダイアログで、検証規則を選択し、必要に応じて規則を構成します。
  6. 「失敗処理」タブをクリックして、ルールに違反した場合に表示するメッセージを構成します。

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

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

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

19.2.3 デフォルトのエラー処理に関する必知事項

例外が発生すると、デフォルトの動作ではADF Facesのエラー・ダイアログにリーフレベル・エラーのみ表示されます。ADFコントローラのデフォルトのエラー処理メカニズムは、ページ・バインディング・コンテナから例外のリストを取得し、各エラーの表示方法を決定します。例外がJboExceptionでない場合、Facesエラー・メッセージが例外メッセージとともに表示されます。

例外がJboExceptionの場合、エラー処理メカニズムはネストされた例外に再帰的にドリル・ダウンし、一意の例外ごとに単一のFacesエラー・メッセージを表示します。ただし、例外にJboWarning.HIDE_DETAIL_EXCEPTIONS_HINTがある場合、エラー処理メカニズムはネストされた例外にドリル・ダウンしません。

また、エラー処理メカニズムは、各例外のバインディング・エラーのリストを取得し、エラーをレポートしたバインディングに関連付けられているコンポーネントに対するFacesエラー・メッセージを表示します。

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

ADFでは、ErrorHandlerClassプロパティを使用して、エラーまたは情報メッセージのレポートに使用するエラー・ハンドラを設定できます。エラー・メッセージのコードを作成する必要はなく、DataBindings.cpxファイルの「プロパティ」ウィンドウを使用してエラー・ハンドラを設定できます。

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

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

  • reportException(): 発生した例外をレポートするためにコールされます。レポートされた例外を分析するようにオーバーライドできます。

  • getDisplayMessage(): 発生したエラーごとにJSFにレポートされるメッセージを戻します。カスタム・エラー・ハンドラで特定の例外をクライアントにレポートする必要がない場合は、nullを戻します。

  • getDetailedDisplayMessage(): 発生したエラーごとにJSFにレポートされるメッセージの詳細部分を、StringオブジェクトまたはHTMLとして戻します。カスタム・エラー・ハンドラで特定の例外をクライアントにレポートする必要がない場合は、nullを戻します。

  • skipException(): ユーザー向けに表示される最終的なエラー・リストに、ネストされた例外から各アイテムを表示するかどうかに応じたブール値を戻します。このメソッド・オーバーライドにより、特定の例外タイプをチェックし、ビジネス・シナリオに基づいて、このタイプをリストに表示するかどうかを判断するロジックを実装できます。

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

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を作成した場合、例外エラー・ハンドラは、次の例に示すようにデフォルトのコンストラクタを起動します。この規則に従うと、クラス名のみで動的な起動が可能になります。

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

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

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

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

  1. デフォルトのDCErrorHandlerImplクラスを拡張するカスタム・エラー・ハンドラを作成します。
  2. このクラスで、DCErrorMessageオブジェクトを戻すgetDetailedDisplayMessageメソッドをオーバーライドします。

    次の例は、カスタム・エラー・ハンドラ・クラスでのgetDetailedDisplayMessageメソッドの実装を示しています。

    public final class MyErrorMessageHandler extends DCErrorHandlerImpl {
        public MyErrorMessageHandler (){
            super();
        }
        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によりメッセージが戻される前に、テキスト・メッセージに対して、必要な前処理をすべて実行しておく必要があります。たとえば、ローカライズしたメッセージの取得や、メッセージの順番を右から左に変更するなどの処理が必要である場合は、メッセージが戻される前に行います。

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

    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>

19.3.2 カスタム・エラー・ハンドラから情報メッセージを表示する方法

エラー・ハンドラを使用すると、ADFモデル・レイヤーのカスタム検証を使用してアプリケーションの警告に対して情報メッセージを表示できます。モデル・レイヤー検証を使用するアプリケーションでは、すべてのエラーと警告について、アプリケーションCPXレベルでカスタム・エラー・ハンドラを使用する必要があります。

始める前に:

モデル・レイヤーでのカスタム検証の動作に関する知識があると役立つ場合があります。詳細は、「エラー処理のカスタマイズ」を参照してください。

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

JDeveloperを起動し、カスタム・エラー・ハンドラを追加するアプリケーションを開く必要もあります。

情報メッセージを表示する手順

  1. データ・モデル・プロジェクトで、JboWarningを拡張するクラスを作成します。次に例を示します。
    public class InformationalMessage extends JboWarning 
    {
        public static final String INFO_PROPERTY = "$InformationalMessage$INFO";
        public InformationalMessage(String message)
        {
            super(message, "", new Object[]{INFO_PROPERTY});
        }
    }
    
  2. アプリケーション・モジュール実装クラスで、メソッドを追加し、クライアント・メソッドとして公開します。次に例を示します。
    public void addInformationMessageTest() 
      {
          addWarning
            (new InformationalMessage("Testing. This is an information message"));
      }
    
  3. 「エラー処理のカスタマイズ」で説明するように、ビュー・コントローラ・プロジェクトで、カスタム・エラー・ハンドラ・クラスを作成します。
  4. 作成したカスタム・エラー・ハンドラをデータ・バインディング・ファイル(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>
    
  5. メソッドをテストするには、クライアント・アプリケーション・モジュール・メソッドを.jspxページにコマンド・ボタンとしてドロップして、情報メッセージを呼び出すことができます。

    .jspxファイルを実行し、ボタンを押すと、情報メッセージが表示されます。

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

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