Oracle Application Development Framework(Oracle ADF)は、Strutsフレームワークを拡張してOracle ADFモデル・レイヤーに統合します。Oracle ADFはStruts仕様に完全に一致した真の統合を提供するため、Webアプリケーション開発を簡単に、そして短時間で行うことができます。JDeveloperはStrutsの使用を完全にサポートし、Struts構成ファイル用にビジュアル・エディタとXMLエディタの両方を提供します。さらに、Struts単体、またはOracle ADFに統合されたStrutsを使用するアプリケーションの構築を簡単にする、その他の機能も用意されています。
Strutsテクノロジを使用したプロジェクトをJDeveloperで開始すると、基本的なStrutsコンポーネントがすべて作成されます。これには、web.xml
ファイル内の必須定義、Struts構成ファイル、およびStrutsの国際化機能で使用されるリソース・ファイルが含まれます。
この章では、Oracle ADFとStrutsの統合について、概要を説明します。
Apache Software FoundationのStrutsフレームワークは、Model-View-Controller(MVC)デザイン・パターンを実装するアプリケーションの作成をサポートします。このデザイン・パターンでは、表示コード(HTMLやタグ・ライブラリなど)が、表示されるデータ・モデルやアプリケーションでアップデートされるデータ・モデルのフロー制御ロジック(Strutsコントローラおよびアクション・クラス)から明確に分離されます。
モデルは、アプリケーション・データとビジネス・ロジックのためのリポジトリです。モデルの機能の1つは企業情報システムに対するデータの取得と永続化ですが、ビューによるアクセスが可能な方法でデータを公開し、ビューから入力されるデータを検証および使用するためのビジネス・ロジック・レイヤーを実装することもモデルの役割です。アプリケーション・レベルでは、モデルはユーザー・インタフェースと表示されるビジネス・データの間の検証および抽象化レイヤーとして機能します。Oracle ADFを使用したモデル・レイヤーの作業の詳細は、「Oracle ADFモデル・レイヤー概要」を参照してください。
ビューは、モデル・データをレンダリングします。ビュー・コード自体にはハードコードのアプリケーションまたはナビゲーションのロジックは含まれませんが、ユーザーのロールに基づく条件付きデータ表示といったタスクを実行するロジックが含まれる場合もあります。最終的にビューからレンダリングされたHTMLページ内でエンド・ユーザーがあるアクションを実行すると、コントローラにイベントが送信され、コントローラによって次の動作が決定されます。Strutsアプリケーションは通常JSPページをビュー・レイヤーに使用しますが、他のテクノロジも使用できます。Oracle ADFにおけるビュー・レイヤーでの作業の詳細は、「ビュー・テクノロジにおけるOracle ADFデータ・バインディングの概要」を参照してください。
ビューで実行されるすべてのユーザー・アクションは、コントローラを介して送信されます。コントローラは、ブラウザからのリクエストの内容とコントローラ自身のプログラミングまたはメタデータに基づいて、次に行う動作を決定します。Strutsでは、基本のコントローラ機能はアクション・サーブレットに実装されています。Oracle ADFとStrutsの統合にはこの他のコントローラ・コンポーネントへの拡張が含まれ、開発者に大きなメリットをもたらします。ここでは、その基本機能について簡単に説明します。
アクション・クラス
org.apache.struts.action.Action
はActionServlet
クラスの拡張クラスで、クライアント・リクエストに応えて1つ以上の操作を実行します。アクション・クラスはexecute()
メソッドを使用してリクエストを処理し、コントロールのフォワード先(例: Webページか別のアクションか)を指定するアクション・フォワード・オブジェクトを戻して適切なレスポンスを提供します。デフォルトでは、execute()
メソッドはNULL
を戻します。このため、Struts単体のアプリケーションでは必ずベースのAction
クラスをサブクラス化する必要があります。
アクション・マッピング・クラス
アクション・マッピングは、コントローラがリクエストを受け取ったときにコールするアクション・クラスに関して、Strutsコントローラ・サーブレットが認識しておく必要のある情報を提供します。この情報は、Struts構成ファイル(XMLファイル)内の<action>
要素として定義します。Strutsフレームワークはこのファイルを解析し、正しいデフォルト値に初期化された適切なオブジェクトを作成します。org.apache.struts.action.ActionMapping
クラスが、<action>
要素に指定された情報を表します。
アクション・フォワード・クラス
org.apache.struts.action.ActionForward
クラスは、アクション・クラスが実行されたときにコントローラがコントロールを送信する送信先です。アクション・マッピングと同様、アクション・フォワードもStruts構成ファイルに、通常は<action>
要素内の<forward>
要素として定義します。
Strutsアーキテクチャとベース・クラスの詳細は、http://struts.apache.org/index.html
を参照してください。
Oracle ADFとStrutsの統合は、次のキー要素で構成されています。
DataAction
およびDataForwardAction
クラスは、Oracle ADF/Struts統合の中核となるコンポーネントです。これらはStruts Action
クラスのサブクラスで、データ・バインドされたWebページ用にOracle ADFモデルのバインディング・コンテキストを準備します。データ・バインドされたWebアプリケーションは、Struts構成ファイル内のエントリを介して、これらのクラスを使用します。
ベースのStruts Action
クラスと異なり、これらのクラスは一連の機能を提供するため、多くの場合さらにサブクラス化しなくても使用できます。サブクラス化が必要な場合には、これらのクラスを使用することでコーディング過程を簡素化できます。これらは、交換可能なリクエスト処理ライフサイクルを実装します。このライフサイクルはOracle ADFバインディング・コンテナを認識し、自由にカスタマイズできます。
完全修飾クラス名はoracle.adf.controller.struts.actions.DataAction
およびoracle.adf.controller.struts.actions.DataForwardAction
(ページ・フロー・ダイアグラムではデータ・ページとして表示される)で、データ・バインドされたWebページ用にバインディング・コンテキストを準備します。DataForwardAction
およびDataAction
クラスは、org.apache.struts.action.Action
を拡張します。
注意: DataForwardAction はDataAction のサブクラスですが、ベース・クラスとの違いは、ページ・フロー・ダイアグラムでデータ・アクション・コンポーネントではなくデータ・ページ・コンポーネントとともに使用されるという点のみです。これらのコンポーネントの詳細は、「データ・バインドされたStrutsページ・フロー内のデータ・ページとデータ・アクション」を参照してください。
|
Oracle ADFとStrutsの統合では、DataAction
およびDataForwardAction
クラスがOracle ADFライフサイクル・インタフェースを実装します。このインタフェースは、WebページのアクションをADFモデルのデータ・バインディングに接続するために必要なコードを提供します。実行時には、ライフサイクル・オブジェクトがWebページに必要な正しいバインディング・コンテナをコールし、レンダリングするデータを準備するよう伝えます。バインディング・コンテナは、データをプールしてローカルに格納した後で、ページをレンダリングします。ライフサイクル・オブジェクトは、Webページのレンダリング前に再度データベースへのラウンドトリップを行わないため、レンダリング処理中のアプリケーション・パフォーマンスが向上します。
handleLifecycle()
メソッドは、連続した操作を設定された順序でコールし、ライフサイクル内のほとんどの作業を行います。次の図は、oracle.adf.controller.lifecycle.PageLifecycle
クラスのこのメソッドによって実行されるステップを示しています。図に続く表では、各ステップでの処理を説明します。
次の表は、handleLifecycle()
メソッドの図の詳しい説明です。
ステップ | 説明 |
---|---|
|
handleLifecycle() メソッドが実行する最初のステップは、ライフサイクル・コンテキストの初期化です。コンテキスト・オブジェクトには、関連するリクエスト、バインディング・コンテナおよびライフサイクル・オブジェクトの値が格納されています。Strutsアプリケーションでは、コンテキストはLifecycleContext のサブクラスであるoracle.adf.controller.struts.actions.DataActionContext のインスタンスです。handleLifecycle() メソッドはライフサイクル・コンテキストのinitialize() メソッドをコールします。
|
|
次にhandleLifecycle() は、実行するイベントのリストを、ライフサイクル・メソッドbuildEventList() でリクエスト・オブジェクトから取得して構築します。
|
|
ここで、handleLifecycle() メソッドは、ステップ1で取得したバインディング・コンテナに対してgetAttribute("bindings") をコールし、モデル・データ・バインディングをチェックします。モデル・データ・バインディングが存在する場合には、リクエストからの更新を受け取るデータ・モデルが、ライフサイクルのこのフェーズで準備されます。このフェーズでは、状態トークンの検証も行われます。
ライフサイクル・インスタンスには、関連するモデル・バインディングがない場合もあります。その場合、ライフサイクルはユーザー・インタフェースでのみ作動するイベントをコールできます。たとえば、データ・バインディングを使用しないカスタムのページ・ナビゲーション・イベントをコールできます。ヘルプ・ボタンに連動するイベントを作成し、ユーザーに対してWebアプリケーション用のHTMLページを表示することも可能です。 関連するモデル・バインディングがない場合、 |
|
イベントによっては、モデルの更新を禁止する必要があります。たとえば、データ変更へのロールバックを実行するイベントの場合、モデルの更新を禁止します。
|
|
ここで、handleLifecycle() はリクエストから新しいデータ値を収集し、モデルをその値で更新します。
|
|
ここで、handleLifecycle() は、現在のライフサイクル・インスタンスに関連するバインディング・コンテナに対してvalidateInputValues() をコールし、モデルへの更新を検証します。
|
|
次に、handleLifecycle() はライフサイクル・インスタンスに対してprocessComponentEvents() をコールします。このメソッドは、開発者が作成して名前を付ける名前付きイベントと、ページ上にドロップしたデータ・バインディングに連結されたイベント(アクション・バインディング)の両方を処理します。
独自の名前付きイベント作成の詳細は、「Oracle ADFの名前付きイベント」を参照してください。 |
|
メソッドは、親クラスをサブクラス化しなくても、データ・アクションまたはデータ・ページ上にドラッグ・アンド・ドロップできます(「データ・アクションへのビジネス・サービス・メソッドの追加」を参照)。handleLifecycle() メソッドはライフサイクル・インスタンスに対してinvokeCustomMethod() をコールし、このようなカスタム・メソッドをここで実行します。
|
|
このステップでは、現在のライフサイクル・インスタンスに関連するバインディング・コンテナに対し、アクションまたはページに対するすべてのモデルの更新が完了したことを通知します。ここで、handleLifecycle() メソッドはバインディング・コンテナ・インスタンスに対してrefreshControl() をコールします。
|
|
ここで、handleLifecycle() メソッドはライフサイクル・インスタンスに対してfindForward() をコールします。Strutsアプリケーションの場合、findForward() はstruts-config.xml ファイル内の<forward> 要素の値を検索し、これをデータ・アクション・クラスまたはサブクラスのexecute() メソッドに渡します。
|
ライフサイクル・メソッドをオーバーライドすれば、Oracle ADFアプリケーションの動作をカスタマイズできます。Strutsベースのアプリケーションの場合、DataAction
またはDataForwardAction
クラスをサブクラス化して、主要なライフサイクル・メソッドをオーバーライドできます。アプリケーション全体で特定の動作をするようにライフサイクルを変更する場合、またはライフサイクル内のステップで繰返しコールされるメソッドの動作を変更する場合には、ライフサイクル自体をサブクラス化する必要があります。詳細は、「Oracle ADFライフサイクル・プラグインの使用」を参照してください。
注意: 上の表に記載されたライフサイクルの各フェーズの順番を変更することはできません。 |
イベントは、特定のコマンドに対して実行される特定の操作です。一般には、Webページ内のボタンまたはリンクによって実行されます。たとえば、ユーザーが「次へ」ボタンをクリックすると、Nextイベントがトリガーされます。Nextはイベント名です。イベントに名前を付けることで、イベントのコールとイベント・ハンドラの作成が簡単になります。Webページ上のコマンドがイベントをトリガーすると、イベント・ハンドラがその作業を実行します。Oracle ADFでは、Webアプリケーションでイベントを処理するためのコマンドおよびイベント・ハンドラを簡単に構築するための機能が用意されています。たとえば、次のような機能があります。
イベントを使用して、アクション・バインディングのモデル操作を実行できます。アプリケーション用のビジネス・サービスを作成および登録すると、データ・コントロール・パレットにはビジネス・サービスから使用できる操作が表示されます。ビジネス・サービス内の操作を作成またはカスタマイズした場合も、コントローラ・レイヤーでの作業は必要ありません。Webページまたはデータ・アクションに操作をドラッグするだけです。
アクション・バインディング内の既存メソッドをオーバーライドするカスタム・メソッドを記述できます。たとえば、nextの操作をオーバーライドして動作を変更するには、データ・アクションにコードを追加します。データ・アクションはカスタム・メソッドを検索した後で、アクション・バインディングにメソッドが存在するかどうかをチェックします。このため、カスタム・メソッドが存在する場合、データ・アクションはそちらを先に見つけます。
モデル・レイヤーに依存しないアクション、つまり、操作を実行するためにアクション・バインディングをコールする必要のないデータ・アクションを開発できます。たとえば、Webアプリケーション用のヘルプ・トピックを表示するヘルプ・ボタンをWebページに追加する場合、名前付きのイベントを使用します。
DataAction
またはDataForwardAction
クラスをサブクラス化せずに、イベントを使用して新しいページへフォワードできます。名前付きイベントを使用して、Webページ内のデータ・アクションまたはデータ・フォワード・アクションに対するフォワードを定義できます。具体的には、アクションのフォワードname
属性の値を、Webページ内の関連するイベントの名前と同じにします。Oracle ADFアクション・サブクラスで、アクション・サブクラスとアクション・バインディングのどちらにも定義されていないイベントが発生すると、そのイベントはフォワードの名前であると判断されます。
注意: Oracle ADFデータ・アクション・クラスとOracle ADF UIXは、どちらもイベントを使用します。一般には、Oracle ADF UIXとStrutsを1つのアプリケーションで使用している場合、イベントの管理においてはデータ・アクション・クラスがUIXサーブレットに優先します。データ・アクション・クラスが処理方法のわかっているイベントとして認識しなかったイベントは、UIXサーブレットによって処理されます。 |
Strutsアクション・マッピング・クラスは、Struts構成ファイル内の<action>
要素に構成された情報を表します。DataActionMapping
クラスは、基本的なStrutsデータ・アクション・マッピング・クラスを拡張し、ADFデータ・バインディングに関連した多くのカスタム・アクション・プロパティをサポートします。DataActionMapping
クラスは、アクションがレンダリングするページのタイプ(JSP、UIXなど)に基づいて、使用するライフサイクル・クラスを決定します。また、DataAction
およびDataForwardAction
クラスに対する次のプロパティの定義と処理も行います。
modelReference
: データ・アクションで使用するバインディング・コンテナの名前。
methodName
: invokeCustomMethod()
のライフサイクル・フェーズ中にデータ・アクション内で実行されるカスタム・メソッドを含むアクション・バインディングの名前。
numParams
: カスタム・メソッドに対するパラメータの数。
paramNames
: 各メソッド・パラメータの値を取得するEL式。
resultLocation
: メソッドの結果を格納する場所を表すEL式。
<action>
要素メタデータに<set-property>
要素を追加する場合には、DataActionMapping
クラスをサブクラス化して追加の要素を処理する必要があります。
DataActionMapping
クラスは、oracle.adf.controller.struts.actions
パッケージに含まれます。このクラスは、org.apache.struts.action.ActionMapping
クラスを拡張します。
デフォルトでは、Oracle ADF WebアプリケーションのStrutsフォームはデータ・フォームBeanを使用します。データ・フォームBeanは、あらゆるバインディング・コンテナの属性を動的にフォームに提供するため、アプリケーションが必要とするActionForm
Beanを作成する必要がなくなります。
データ・コントロール・パレットからJSPページへデータ・バインディングをドラッグ・アンド・ドロップすると、実行時にOracle ADFはアプリケーション用のデータ・フォームBeanを自動的に参照します。関連するバインディング・コンテナ内の各値バインディングに対し、JDeveloperでは各バインディング用のget
およびset
メソッドが動的に作成されます。
注意: データ・フォームBeanを使用する場合、JDeveloperでは<form-property> 要素のstruts-config.xml ファイルへの移入は行われません。アプリケーションは、関連するバインディング・コンテナから必要な値を取得します。
|
実行時には、関連するアクション・クラス(DataAction
とDataForwardAction
どちらかのインスタンス、またはサブクラス)がデータ・フォームBeanを使用してフォームに移入し、更新があればこれを送信します。
次のコードは<html:form>
タグの例で、データ・フォームBeanの動作を示しています。
<html:form action="MyDataAction.do"> <html:text property="dname"> </html:form>
実行時には、MyDataAction
クラスがdname
プロパティを解決する必要があります。Oracle ADFでは、HTMLフォームにはデータ・アクションが付随し、これがデータ・フォームBeanに連結しています。フォームはプロパティを解決するためにデータ・フォームBeanへ移動します。データ・フォームBeanは、バインディング・コンテナに該当する名前のバインディングがないかどうかを問い合せます。バインディングが存在する場合バインディング・コンテナはそのバインディングを戻し、データ・フォームBeanはそのバインディングの値をHTMLフォームに移入します。
警告:
|
データ・フォームBeanはoracle.adf.controller.struts.forms.BindingContainerActionForm
のインスタンスです。oracle.adf.controller.struts.forms.BindingContainerActionForm
は、apache.commons.beanutils.DynaBean
インタフェースを実装するorg.apache.struts.action.ActionForm
のサブクラスです。
Oracle ADF Webアプリケーションは、Oracle ADFバインディング・フィルタを使用して、バインディング・コンテキストへのアクセスが必要なHTTPリクエストを前処理します。バインディング・フィルタはサーブレット・フィルタで、次の処理を行います。
フィルタを初期化する際に、web.xml
ファイルにフィルタ・パラメータとして指定されている名前で文字コードをオーバーライドします。フィルタ<init-param>
のパラメータ名はencoding
です。
ユーザーのHTTPセッション用にOracle ADFモデルのバインディング・コンテキストを初期化します(バインディング・コンテキストの詳細は、「StrutsとOracle ADFモデル・レイヤーの実行時統合」を参照してください)。
同じブラウザ(フレームセットなど)から送信されるHTTPリクエストをシリアライズし、マルチスレッドの問題を回避します。
リクエストが送信されることをデータ・コントロール・インスタンスに通知し、リクエスト前の設定を可能にします。
レスポンスがクライアントに送信された後でデータ・コントロール・インスタンスに通知し、リクエスト後のクリーンアップを可能にします。
バインディング・フィルタは、最初にコントロール・バインディングをWebページに追加したとき、またはページ・フロー・ダイアグラムでビジネス・サービス・メソッドをデータ・アクションにドラッグしたときに作成され、アプリケーションのweb.xml
ファイル内に自動的に構成されます。
たとえば、JSPページ用のStrutsベースのOracle ADFアプリケーションにデータ・ページを作成し、関連するWebページにコントロール・バインディングをドラッグした場合には、次のような要素が追加されます。
注意: この構成ファイルは、参照専用です。ほとんどの場合、このファイルを変更する必要はありません。 |
. . <!-- Servlet context parameter, which determines which CPX file the filter reads at runtime to define the application binding context. --> <context-param> <param-name>CpxFileName</param-name> <param-value>DataBindings</param-value> </context-param><!-- ADF Binding Filter Class Setup --> <filter> <filter-name>ADFBindingFilter</filter-name> <filter-class>oracle.adf.model.servlet.ADFBindingFilter</filter-class> <!-- Default language encoding, which can be set in Tools>Preferences dialog --> <init-param> <param-name>encoding</param-name> <param-value>windows-1252</param-value> </init-param></filter> <!-- A filter mapping links the filter to a static resource or servlet in the web application. When a mapped resource is requested, the filter is invoked. --> <filter-mapping> <filter-name>ADFBindingFilter</filter-name> <url-pattern>*.jsp</url-pattern> </filter-mapping>. . <filter-mapping> <filter-name>ADFBindingFilter</filter-name> <servlet-name>action</servlet-name> </filter-mapping> <filter-mapping> <filter-name>ADFBindingFilter</filter-name> <servlet-name>jsp</servlet-name> </filter-mapping>
注意: アプリケーションに複数のフィルタがある場合、実行する順番でweb.xml に記載されている必要があります。実行時には、ファイル内に記載された順番でフィルタがコールされます。
|
Oracle ADFバインディング・フィルタはjavax.servlet.Filter
インタフェースを実装する、捕捉フィルタです。
追加情報は、次を参照してください。
サーブレット・フィルタの詳細は、http://java.sun.com/products/servlet/docs.html
を参照してください。
捕捉フィルタの詳細は、http://java.sun.com/blueprints/patterns/InterceptingFilter.html
を参照してください。
Oracle ADFには、Strutsベースのアプリケーションを短時間で簡単に構築するための様々な機能が用意されています。
JDeveloperでStrutsベースのアプリケーションを構築する際に使用する主な作業環境は、Strutsページ・フロー・ダイアグラムです。これは、Struts構成ファイルを視覚的に表したものです。ページ・フロー・ダイアグラムで行った変更はファイルに反映され、Struts構成ファイルを手動で編集して行った変更はページ・フローに反映されます。ページ・フロー・ダイアグラムは、次の作業を行うためのワークベンチです。
アプリケーションのページ・フローの作成
編集するWebページおよびStrutsアクションの選択
アプリケーションの実行およびデバッグ
Strutsページ・フローに必要な標準オブジェクトはコントロール・パレットに表示されます。コントロール・パレットには、Oracle ADFモデルを使用するデータ・バインドされたページの処理に使用する、専用のデータ・アクションとデータ・ページも含まれます。データ・アクション・コンポーネントは、Strutsアクション・クラスのOracle ADFサブクラスを表します。データ・ページは、アクション・フォワードおよびフォワード先Webページと連結されたデータ・アクション・サブクラスを表します。これらのコンポーネントの詳細は、「Oracle ADFデータ・アクション・クラスとデータ・フォワード・アクション・クラス」を参照してください。
コンポーネント・パレットには、Strutsフォワード・アクションを表すための専用のページ・フォワード要素も含まれます。このアクションは、常に指定されたフォワード先Webページへの単純なフォワードを実行します。ページ・フォワードを使用すると、ある程度間接的かつ柔軟にWebページを操作できます。基になっているWebページの名前をStruts構成ファイルのアクション・マッピングで変更しても、そのページへフォワードするすべてのコンポーネントを変更する必要はありません。
コンポーネント・パレットからページ・フロー・ダイアグラムへコンポーネントをドラッグすれば、ファイルを直接編集しなくても、アプリケーションが必要とするStrutsアクション・マッピング要素とアクション・フォワードを作成できます。ダイアグラムには、資料用のコメントを追加することもできます。次のダイアグラムは、データ・ページとデータ・アクションがそれぞれ2つあり、ページ・リンク(点線の矢印、ここではページとアクションの明示的なリンクを表す)とアクション・フォワード(実線の矢印)がそれらを結んでいる単純なページ・フローを表しています。
ページ・フロー・ダイアグラムには、この他に次の機能があります。
大規模なページ・フローを作成およびナビゲートするための手段
フローのレイアウトを整理するためのツール
ダイアグラムで使用するフォントと色のカスタマイズ
「リンク元ビュー」タブからは、Struts構成ファイル内のXMLにアクセスできます。このXMLテキスト・エディタは、ファイル内のXML情報へドリルダウンし、ページ・フロー・ダイアグラムではできない細かな追加や編集を行う場合に便利です。またstruts-config.xml
ファイルの構造を理解している開発者の場合、XMLエディタを使用するとより短時間でファイルを更新できます。
XMLエディタは、ページ・フロー・ダイアグラムに完全に準拠および同期化されています。Struts構成ファイルはどちらのモードでも編集可能です。
プロパティ・インスペクタは、基になっているStruts構成ファイルに同期化されています。プロパティ・インスペクタでは、XMLメタデータを直接編集できます。プロパティ・インスペクタでは、Strutsタグに対し、Struts構成ファイルの内容から使用可能な値を表示することもできます。たとえば、Webページに<html:form>
タグを追加した場合、Struts構成ファイルで現在定義されているすべてのアクションをドロップダウン・リストに表示できます。
HTML、JSTL、Strutsおよびその他のカスタム・タグ・ライブラリでWebページを作成し、データのビューを実装できます。JSPページの拡張には、Strutsフレームワークとともに動作する多数のカスタムJSPタグ・ライブラリ群を使用できます。すべてのStrutsタグ・ライブラリには、エディタでJSPページを開いた後にJDeveloperのコンポーネント・パレットからアクセスできます。
Oracle ADFモデル・レイヤーと統合されたStrusベースのアプリケーションでは、各タイプのビジネス・サービス用に実装されたデータ・コントロール・オブジェクトが、コントローラ・レイヤーにモデル・データを公開します(次の図を参照)。
実行時、HTTPリクエストはサーブレット・フィルタであるOracle ADFバインディング・フィルタを通過し、前処理が行われます。バインディング・フィルタはOracle ADFモデルのバインディング・コンテキストを初期化し、リクエストが送信されることをデータ・コントロール・インスタンスに通知して、リクエスト前の設定を可能にします。
バインディング・コンテキストには、一連のバインディング・コンテナとデータ・コントロールが格納されています。バインディング・コンテナは、Webアプリケーション内の1つページで使用されている、関連するコントロール・バインディングとイテレータ・バインディングの集まりです。データ・コントロールはビジネス・サービスの実装を抽象化し、バインディング・レイヤーがすべてのサービスのデータに一貫した方法でアクセスできるようにします。
次に、データ・アクション・クラスにコントロールが渡されます。このクラスの機能のほとんどは、Oracle ADFライフサイクルの実装にカプセル化されています。Strutsベースのアプリケーションで使用されるライフサイクルは、StrutsLifecycle
のサブクラスです。
Oracle ADFライフサイクルは次の処理を実行します。
Webページで必要な正しいバインディング・コンテナをコールし、レンダリングするデータを準備するよう伝えます。
ユーザーが送信したモデルの更新を処理および検証します。
すべてのモデルの更新が完了した時点で、バインディング・コンテナに通知します。
Oracle ADFを使用したモデル・レイヤーの作業の詳細は、「Oracle ADFモデル・レイヤー概要」を参照してください。
ADFデータ・コントロールをページまたはページ・フォワードで使用する場合、Webページにデータ・アクションが関連付けられているか、またはWebページがデータ・ページの一部である必要があります。ADFデータ・コントロールをアクション・クラスに関連付ける前にコンポーネント・パレットからWebページにドラッグすると、現在のコンテキストからデータ・ページまたはデータ・アクションを選択するよう求めるダイアログが表示されます。このダイアログでは、データ・バインドされる必要のあるすべてのページの変換に使用するデフォルトの選択肢も設定できます。
Strutsページ・フロー・ダイアグラムを使用してデータ・ページを作成すると、struts-config.xml
ファイルが更新されます。たとえば、空のページ・フロー・ダイアグラムにデータ・ページ・アイコンをドラッグして名前を/myPage
に変更すると、関連するWebページがまだ作成されていないことを示す警告アイコンがデータ・ページ・アイコンの上に表示されます(次の図を参照)。
同時に、JDeveloperではstruts-config.xml
ファイルに次のエントリが作成されます。
<action-mappings> <action path="/myPage" className="oracle.adf.controller.struts.actions.DataActionMapping" type="oracle.adf.controller.struts.actions.DataForwardAction" name="DataForm"parameter=unknown"> </action> </action-mappings>
次の表は、アクション・マッピングの属性およびサブ要素の説明です。
属性または要素 | 説明 |
---|---|
action
|
<action> 要素は、リクエスト・パスからそのリクエストの処理に使用されるアクション・クラスへのマッピングを指定します。
|
path
|
データ・ページの名前。 |
className
|
このアクション・マッピング・オブジェクト用に使用するアクション・マッピング・サブクラスの完全修飾Javaクラス名。Oracle ADFのStrutsアプリケーションで使用する場合、デフォルトは、oracle.adf.controller.struts.actions.DataActionMapping です。このクラスは、アクションがフォワードするページのタイプに基づいて、使用するライフサイクル・クラスを決定します。詳細は、「Oracle ADFデータ・アクション・マッピング・クラス」を参照してください。
|
type
|
このアクション・マッピング用にリクエストを処理するアクション・サブクラスの完全修飾Javaクラス名。データ・ページを使用する場合、デフォルトのクラス名はoracle.adf.controller.struts.actions.DataForwardAction です。
|
name
|
このアクション・マッピングに関連付けられているフォームBeanがある場合、その一意な名前。データ・ページの場合、デフォルトのフォームBeanはDataForm です。デフォルトでは、すべてのデータ・アクションとデータ・ページで1つのフォームBeanを共有します。詳細は、「Oracle ADFデータ・フォームBean」を参照してください。
|
parameter
|
このアクション・マッピングが選択したアクション・オブジェクトに追加の情報を渡す、汎用の構成パラメータ。関連するWebページを指定すると、この属性の値はunknown からそのページ名に変わります。
|
Strutsアプリケーション内に関連するWebページ(この例ではmyPage.jsp
)を作成すると、警告アイコンが消え、通常のデータ・ページ・アイコンが表示されます(次の図を参照)。
同時に、JDeveloperではstruts-config.xml
ファイル内のアクション・マッピングが次のように更新されます(太字が変更箇所)。
<action-mappings> <action path="/myPage" className="oracle.adf.controller.struts.actions.DataActionMapping" type="oracle.adf.controller.struts.actions.DataForwardAction" name="DataForm" parameter="/myPage.jsp"> <set-property property="modelReference" value="myPageUIModel"/> </action> </action-mappings>
アクション・マッピングのparameter
属性の値が、関連するWebページ・ファイルの名前に更新されます。また、アクション内に<set-property>
定義が追加され、プロパティがmodelReference
に、値がバインディング定義の名前(pageNameUIModel
)に設定されます。関連するWebページに最初のデータ・コントロールを追加すると、次のプロジェクト・ファイルも作成されます。
クライアント・バインディング定義ファイル(myPageUIModel.xml
): Webページ専用のファイルです。クライアント・バインディング定義ファイルは、プロジェクト内のWebページごとに1つ作成されます。
クライアント・プロジェクト定義ファイル(DataBindings.cpx
): アプリケーションのビジネス・サービスに登録されているOracleデータ・コントロールを作成します。クライアント・プロジェクト定義ファイルは、プロジェクトごとに1つのみ作成されます。
Strutsページ・フロー・ダイアグラムを使用してデータ・アクションを作成すると、struts-config.xml
ファイルが更新されます。たとえば、空のページ・フロー・ダイアグラムにデータ・アクション・アイコンをドラッグし、その名前を変更すると、次のようなアイコンが表示されます。
JDeveloperではstruts-config.xml
ファイルに次のエントリが作成されます。
<form-beans> <form-bean name="DataForm" type="oracle.adf.controller.struts.forms.BindingContainerActionForm"/> </form-beans> <action-mappings> <action path="/myAction" className="oracle.adf.controller.struts.actions.DataActionMapping" type="oracle.adf.controller.struts.actions.DataAction" name="DataForm"/> </action-mappings>
このエントリと前述のデータ・ページ用のエントリの主な違いは、次の2点です。
アクション・タイプがoracle.adf.controller.struts.actions.DataAction
です。
データ・アクション用のアクション・マッピングではparameter
属性は使用されません。
このデータ・アクションには関連するWebページがないため、次に表示するページへリダイレクトするフォワードを作成する必要があります。<forward>
要素を定義するには、「forward」アイコンをページ・フロー・ダイアグラムにドラッグします。フォワード先には、データ・ページ、ページ・フォワード、Webページまたは他のデータ・アクションを指定できます。この例では、WebページmyPage.jsp
へフォワードします(次の図を参照)。
Webページへのフォワードを追加すると、データ・アクション用のアクション・マッピングが次のように更新されます(太字が変更箇所)。
<action path="/myAction" className="oracle.adf.controller.struts.actions.DataActionMapping" type="oracle.adf.controller.struts.actions.DataAction" name="DataForm"> <set-property property="modelReference" value="myPageUIModel"/> <forward name="success" path="/myPage.jsp"/> </action>
次の表は、最終的なアクション・マッピングの属性およびサブ要素の説明です。
属性または要素 | 説明 |
---|---|
action
|
<action> 要素は、リクエスト・パスからそのリクエストの処理に使用されるアクション・クラスへのマッピングを指定します。
|
path
|
データ・アクションの名前。 |
className
|
このアクション・マッピング・オブジェクト用に使用するアクション・マッピング・サブクラスの完全修飾Javaクラス名。Oracle ADFのStrutsアプリケーションで使用する場合、デフォルトは、oracle.adf.controller.struts.actions.DataActionMapping です。このクラスは、アクションがフォワードするページのタイプに基づいて、使用するライフサイクル・クラスを決定します。詳細は、「Oracle ADFデータ・アクション・マッピング・クラス」を参照してください。
|
type
|
このアクション・マッピング用にリクエストを処理するアクション・サブクラスの完全修飾Javaクラス名。データ・アクションを使用する場合、デフォルトのクラス名はoracle.adf.controller.struts.actions.DataAction です。
|
name
|
メソッド名と追加のJavaBean構成プロパティの初期値を指定します。囲んでいる要素を表すオブジェクトがインスタンス化されると、指定されたプロパティ用のアクセッサがコールされ、指定された値が渡されます。この例では、プロパティがmodelReference に、値がバインディング定義の名前(pageNameUIModel )に設定されています。
|
set-property
|
メソッド名と追加のJavaBean構成プロパティの初期値を指定します。囲んでいる要素を表すオブジェクトがインスタンス化されると、指定されたプロパティ用のアクセッサがコールされ、指定された値が渡されます。この例では、プロパティがmodelReference に、値がバインディング定義の名前(pageNameUIModel )に設定されています。
|
forward
|
アクションがフォワードするページまたは他のリソース。この例では、JSPページmyPage.jsp へフォワードします。
|
データ・ページまたはデータ・アクションを使用するケースについては、「データ・ページまたはデータ・アクションの使用」を参照してください。
Oracle ADFとStrutsの統合では、個々のイベントの操作からWebアプリケーション全体の動作変更まで、アプリケーション開発を簡単にするためのいくつかのオプションが用意されています。
データ・ページは、データ・バインドされたWebページへフォワードするアクションを追加する場合にお薦めするコンポーネントです。データ・ページは次の場合に使用します。
Webページへ直接フォワードするデータ・アクションがある場合。ページ・フロー・ダイアグラムでは、データ・ページはデータ・フォワード・アクション・クラスのインスタンス、フォワード遷移およびWebページの組合せを表します。
複雑なページ・フロー・ダイアグラムを簡潔にする場合。データ・ページを使用するとページ・フロー内の要素数が減り、複雑なアプリケーション・ダイアグラムが見やすくなります。
データ・アクションは次の場合に使用します。
Webページをレンダリングする前に複数の操作を実行する必要がある場合(このプロセスはデータ・アクションの連鎖と呼ばれます)。Webページに直接フォワードしない操作を実行するには、データ・アクションを使用してください。たとえば、次のダイアグラムのデータ・アクションは、現在の行を設定した後で、次のWebページ上の編集フォーム用にデータを準備するデータ・ページへフォワードします。この例では、現在の行の設定に専用のデータ・アクションが必要です(次の図を参照)。
アプリケーションの設計内容によっては、データ・ページを使用するかわりに、別のページ・フォワードまたはページへフォワードするデータ・アクションを使用することもあります。たとえば、複数のデータ・アクションから1つのページへフォワードする場合などには、この方法が適しています。ページ・フォワードは、フォワード先Webページへの単純なフォワードを実行します。
データ・コントロール・パレットでは、データ・バインドされたStrutsページ・フロー内のデータ・アクションにメソッドをドラッグできます。これは、データ・アクション・クラスをサブクラス化せずにWebアプリケーションに機能を追加するもう1つの方法です。設計時には、データ・アクション用のアクション・マッピングが次のように更新されます。
<set-property property="methodName" value="MyPageUIModel.ActionName"/> <set-property property="resultLocation" value="${requestScope.methodResult}"/> <set-property property="numParams" value="1"/> <set-property property="paramNames[0]" value="${param.paramName0}"/>
実行時には、データ・アクションに実装されたライフサイクルが、ビジネス・サービスによって定義されたメソッドをOracle ADFデータ・コントロールを介して実行します。詳細は、この章の前半に記載したライフサイクルの処理手順表にあるステップ8を参照してください。
注意: 各メソッド・パラメータにはparamNames[] プロパティがあります。パラメータが1つもなく、numParams の値が0に設定されているメソッドには、paramNames プロパティは設定されません。パラメータを必要とするカスタム・メソッドを使用している場合には、Struts構成エディタを使用してparamNames プロパティを追加する必要があります。
|
Oracle ADFとStrutsの統合は、DataAction
およびDataForwardAction
クラスのサブクラス化が最小限ですむように設計されています。どちらのクラスでも、execute()
メソッドはfinalとして宣言されています。ただし、次の場合にはサブクラス化の必要があります。
モデル・レイヤーに依存しない名前付きイベントを開発する場合(「Oracle ADFの名前付きイベント」を参照)
既存のアクション・バインディングの動作をオーバーライドする場合
1つのアクションに対し、ライフサイクルのステップの1つについて動作を変更する場合(「Oracle ADFライフサイクル」を参照)
データ・アクションは、ライフサイクル・メソッド公開の一般的なパターンに従い、その機能のほとんどをライフサイクル・クラスに委譲します。
Strutsベースのアプリケーションの場合、DataAction
またはDataForwardAction
クラスをサブクラス化して、主要なライフサイクル・メソッドをオーバーライドできます。次の場合、ライフサイクル自体をサブクラス化してライフサイクル・プラグインを登録する必要があります。
アプリケーション全般で特定の動作を実行するようにライフサイクルを変更する場合
DataAction
またはDataForwardAction
クラスではオーバーライドできない、ライフサイクル・サブクラス内のメソッドの動作を変更する場合
データ・アクションは、ライフサイクル・メソッドを公開して機能のほとんどをライフサイクル・クラスに委譲する一般的なパターン(Decoratorデザイン・パターンとも呼ばれる)に従います。たとえばhandleError()
は、「Oracle ADFライフサイクル」に記載したライフサイクル・メソッド同様、このパターンに従います。ただし、handleEvent()
のようにこのパターンに従わないメソッドもあります。カスタマイズするメソッドがライフサイクルで1度のみ実行されるステップではない場合は、ライフサイクルをサブクラス化してメソッドを変更する必要があります。ライフサイクルのフェーズと、各フェーズが実行する個々の操作は同じではありません。handleEvent()
の場合、ライフサイクルは各イベントに対してこのメソッドをコールします。つまり2回以上コールされる可能性があるため、後者に該当します。アプリケーション内のすべてのイベントに対するhandleEvent()
の基本的なロジックをカスタマイズすれば、デフォルト操作の前後、またはデフォルト操作のかわりに何かを実行できます。handleEvent()
メソッドは、ライフサイクル・クラスに対してはオーバーライドできますが、データ・アクション・クラスに対してはオーバーライドできません。独自のライフサイクル実装を作成して登録する必要があります。
各データ・アクションをオーバーライドするかわりに、アプリケーション内のすべてのデータ・アクションに対してコードを1度変更する方法も、効果的な開発戦略です。JDeveloperにはStrutsプラグイン実装が含まれており、ライフサイクル・サブクラスを作成して使用できるように、新しいLifecycleFactory
クラスを指定できます。LifecycleFactory
クラスは、抽象クラスであるStrutsPageLifecycleFactory
を実装します。
一部のライフサイクル・メソッドは構成中に使用されるため、Strutsライフサイクルをオーバーライドするには、データ・アクションの構成中に新しいLifecycle
クラスを指定する必要があります。新しいクラスを指定するには、struts-config.xml
ファイルに<plug-in>
要素を追加します。プラグインは、アプリケーション起動時にコンポーネントを動的にロードするためのStrutsメカニズムです。
構成ファイルのエントリは、次の構文で記述します。
<plug-in className="oracle.adf.controller.struts.actions.PageLifecycleFactoryPlugin"> <set-property property="lifecycleFactory" value="mypackage1.myStrutsLifecycleFactory"/> </plug-in>
プロパティは、新しいLifecycleFactory
クラスの名前をアプリケーションに渡すために使用されます。LifecycleFactory
クラスは、抽象クラスであるStrutsPageLifecycleFactory
クラスを実装します。このクラスでは次のメソッドを定義する必要があります。
public StrutsPageLifecycle getPageLifecycle(String path)
例については、DefaultStrutsPageLifecycleFactory
用のjavadocを参照してください。
目的 | ベスト・プラクティス |
---|---|
ADFモデル・レイヤーにアクセスするカスタム・メソッドを作成する。 | ビジネス・サービス・レイヤーにカスタム・メソッドを作成する。 |
表示用のモデル・データを準備し、データ・バインドされた特定のページへフォワードして、そのページからの送信内容を管理するアクションを作成する。 | データ・ページを使用する。 |
ビジネス・サービスによって公開されるカスタム・メソッドを実行するアクションを作成する。 | データ・アクションを使用する。 |
アクション・バインディング内の既存メソッドをオーバーライドする。 | データ・アクションをサブクラス化する。 |
ADFモデル・レイヤーにアクセスしないカスタム・イベントを作成する。 | データ・アクションをサブクラス化して名前付きイベントを作成する。 |
データ・アクションをサブクラス化せずに、イベントを使用して新しいページへフォワードする。 | イベントを使用してアクション・フォワードを定義する。 |
データ・アクションまたはデータ・ページがコールされるたびにコールされる操作を作成する。 | データ・アクションまたはデータ・フォワード・アクションをサブクラス化する。 |
アプリケーション全体でのライフサイクルの動作を変更する(個々のイベントのグローバルな処理方法を変更する場合など)。 | ライフサイクル・プラグインを作成して登録する。 |
アクション・マッピングにプロパティを追加する。 | データ・アクション・マッピング・クラスをサブクラス化する。 |