Strutsユーザガイド
クイックリンク
ホーム
目次
はじめに
モデル コンポーネント
ビュー コンポーネント
コントローラ コンポーネント
リソース
私たちは誰でしょう
2. モデルコンポーネントの構築
2.1 概要

Webアプリケーションの構築の為に用いるドキュメントの要求の多くは、 ビューにフォーカスしています。 しかし、各リクエストの為に必要な処理も、 モデルの観点からさらに明白に定義をするべきです。 一般にモデル コンポーネントの開発者は、要求される 機能のすべてをサポートした、JavaBeansクラスの生成に焦点をあてるでしょう。 特定のアプリケーションが要求するBeanの正確な性質は、 それらの必要条件に依存して、それぞれ異なりますが、 一般的には以下に議論するいくつかのカテゴリに分類することができます。 しかし、Beanの“スコープ”の概念に関する簡単な検討を最初に行う事が大切です。

2.2 JavaBeansとスコープ

Webベースアプリケーション内のJavaBeansは、 属性の異なるコレクションに格納(と参照)する事が可能です。 各コレクションは、そこに格納されたBeanのライフタイムと、 参照範囲のための異なるルールをもっています。 コレクションによって適用された参照可能範囲とライフタイムが、 そのBeanのスコープ とよばれます。 JavaServer Pages(JSP)では下記の用語を使用してスコープを定義しています。 (括弧の中は、Servlet APIでの同等の概念です)

  • page - Beanは単一のJSP ページでのみ参照可能です。 ライフタイムはリクエストの処理中のみです (Servletの service() メソッド内のローカル変数として生成されます)
  • request - Bean は単一のJSPページだけでなく、 このページをincludeしたあらゆるページまたはServlet、 あるいはこのページから転送(forward)されたページでも参照可能です。(Request 属性)
  • session - Beanは個々のユーザセッションに属する複数のリクエストを跨って、 全てのJSPページとServletで参照可能です。(Session属性)
  • application - Bean はWebアプリケーションの一部として、 全てのJSPページとServlet から参照可能です。(Servlet context属性)

同じWebアプリケーション内のJSPページとServletは、 Beanコレクションの同一集合を共有する事を覚えておく事が重要です。 たとえば、Servletのリクエスト属性としてとして格納するBeanは以下のように記述します。

MyCart mycart = new MyCart(...);
request.setAttribute("cart", mycart);

このServletが転送(forward)するJSPページで直接参照するには、 標準のアクションタグを使い、下記のように書きます

<jsp:useBean id="cart" scope="request"
class="com.mycompany.MyApp.MyCart"/>

2.3 ActionForm Beans

メモ:ActionForm Beans は実際にはモデルというよりはビューに近いです。

Strutsフレームワークでは一般的に、アプリケーション内のそれぞれの入力フォームに対して、 ActionForm Bean(このクラスはJavaのクラスである ActionForm クラスの継承クラス)を定義します。 ActionFormBeanは、しばしば"form beans"と呼ばれます。 もし、このBeanをActionMappping コンフィグレーションファイル (“ コントローラコンポーネントの作り方”を参照)に定義した場合、 Struts コントローラServletは、適当なActionメソッドを呼ぶ前に、 自動的に下記のサービスを行います。

  • ユーザセッションの適切なキー下の適切なクラスのBeanのインスタンスか、 チェックします。
  • もし、有効なBeanがセッションスコープ内に存在しない場合、 新しいBeanを自動的に生成し、ユーザセッションに追加します
  • 全てのリクエストパラメータ名に対応する、 Bean内のプロパティ名のセッターメソッドを呼びます。 この操作は、全てのプロパティを選択するアスタリスクワイルドカードを使う場合のJSPの標準アクション<JSP:setProperty>に似た方法です
  • 更新されたActionForm Beanは、値が有効となった状態で、 Actionクラスのperform() メソッドに渡されます

ActionForm Beanをコード化する場合、次の法則を覚えておいてください

  • ActionForm クラス自身は、特定のメソッドのインプリメントを要求しません。それは、これらのActionFormBeanがアーキテクチャ全体の中で果たす役割を示しています。典型的なActionFormBeanは、プロパティセッターとプロパティゲッターメソッドのみを持っており、ビジネスロジックを含みません
  • ActionForm オブジェクトは標準の検証メカニズムを用意しています。 “stub”メソッドをオーバーライドし、そして標準のアプリケーションリソースにエラーメッセージを用意して、Strutsは入力フォームからの入力を自動的に検証します(あなたのメソッドを使います)。 詳細は “ Action Form バリデーション”を参照してください。 もちろん、ActionForm validationを無視して、Actionオブジェクトであなた自身が提供する事も可能です。
  • フォームにある個々のフィールドに対応した、プロパティ(と対応するgetXxx(), setXxx()メソッド)を定義します。 フィールド名とプロパティ名は、通常のJavaBeansの慣例に適合している必要があります。たとえば、入力フィールド名がusernameなら、setUsername() メソッドを呼び出します
  • あなたのActionForm BeanをHTTPとアクションの間のファイヤーウォールと考えてください。全ての要求された属性が存在し、それらが適切な値を保持している事を保障する validateメソッドを利用してください。 検証が失敗したActionFormは、Actionへ処理が渡されないでしょう。
  • さらに、フォーム内にBeanインスタンスを置き、ネストしたプロパティを参照する事が出来ます。 たとえば“customer”Beanをアクションフォーム内に持たせます。 そして、ビューJSP内で “customer.name”プロパティを参照します。 これはcustomer Bean内で customere.getName() または、 customer.setName(String Name)を実行することに相当します。 ネストシンタックスの詳細は“Tag Library Developer Guide”を参照してください
  • 注意:フォーム中にネストしたbeanインスタンスが存在する場合、 公開する属性に気をつけてください。 ActionForm内にある単一のString値を受け取る全てのpublicな属性は、クエリー文字列によってセットされます。必要とされる属性だけを公開するための薄い"wrapper"のようなBeanを内部に配置するのが有効かもしれません。 このwrapperは、ランタイム属性が不当な値にセットされない事を保障するための、フィルタを提供することもできます。

“フォーム”が、ユーザインタフェース中の単一のJSPページに必ずしも一致しないことに注目すべきで、ここで検討します。 それは、複数のページを越えて継承する“フォーム”(ユーザの立場から) をもつ多くのアプリケーションにおいて共通です。 例えば、新しいアプリケーションをインストールする場合に一般的に使われる、 ウィザードスタイルのユーザインタフェースを考えてみてください。 Strutsではフィールドがどのページに表示されたとしても、全てのフィールドのプロパティを含んだ単一のActionFormBeanを定義する事を提案します。 同様に、同じ形式の様々なページは全て同じAction Classにサブミットされるべきです。 この提案に従えば、ページデザイナは様々なページ中のフィールド を組替えることができ、プロセスロジックの変更を行わずに済みます。

2.4 システム状態Beans

Systemの状態は、1セット以上の現在の状態を定義したプロパティをもつJavaBeansクラスとして、通常表されます。ショッピングカートシステムでは、例えば、個々の買い物客の為に維持されているカートを表わし、買い物客が購入の為に選んだアイテム(他のものも)をもったBeanを含むでしょう。 それとは別に、システムはさらに、利用できるアイテムのカタログと、それらの在庫状況と同様に、ユーザプロファイル情報(配送住所、クレジットカード情報)などの異なるBeanも含むでしょう。

小規模システムや長時間維持する必要のない状態情報は、 システム状態Beanのセットが、全ての必要な詳細情報を持っているかもしれません。 または、よくある事ですが、システム状態Beanは、外部データベース (CustomerBeanオブジェクトのように、それはCUSTOMERSテーブル中のある行に相当する)に永遠に格納される情報を表し、必要に応じてサーバのメモリに作成され、削除される事もあります。 エンティティEnterprise JavaBeanは、さらに大規模アプリケーションの中でこの目的の為に使用されます。

2.5 ビジネスロジックBeans

アプリケーションの目的のために設計された機能ロジックは、 JavaBeansのメソッド呼び出しとしてカプセル化するべきです。 これらのメソッドはシステム状態Beanのために使用された同じクラスの一部かもしれません。あるいは、ロジックの実行専門の他のクラスの中にあるかもしれません。 後者の場合では、通常、引数としてこれらメソッドに操作されるシステム状態Beanを渡す必要があります。

最大のコード再利用としては、ビジネスロジックBeanは、どこのWebアプリケーションで実行されているかを知らなくてもよいように、設計され実装されるべきです。もし、javax.servlet.*のimportをあなたのBean中のクラスに見つけたら、Webアプリケーション環境にこのビジネスロジックBeanを拘束している事になります。 Actionクラス(後述されるようなコントローラーの役割の一部)が、HTTPリクエストから必要な情報を変換して、ビジネスロジックBean上のプロパティセッター呼び出し処理をするようにし、後に、execute()メソッドの呼び出しをするように、再整理する事を考慮してください。 そのようなビジネスロジッククラスはそれが最初に構築されたWebアプリケーション以外の環境でも再利用する事が可能となります。

アプリケーションの複雑さおよび範囲によっては、 ビジネスロジックBeanは引数として渡されたシステム状態Beanと対話する普通のJavaBean、あるいはJDBC呼び出しを使用して、データベースにアクセスするような、普通のJavaBeanかもしれません。 より大きなアプリケーションは、これらBeanが多くの場合、ステートフルあるいはステートレスなEnterprise JavaBeans(EJB)に代ります。

2.6 リレーショナルデータベースへのアクセス

Struts はデータソースをアプリケーションの標準コンフィグレーションファイルに定義出来ます。 また、シンプルなJDBC コネクションプールも提供します。 詳細は、“ The Action Mappings Configuration File”の章と、 Utilities Developer Guideを参照してください。

下記は、Action perfom メソッド内でコネクションを確立する例です。

public ActionForward
       perform(ActionMapping mapping,
               ActionForm form,
               HttpServletRequest request,
               HttpServletResponse response)
{
 try {
   javax.sql.DataSource dataSource =
     servlet.findDataSource(null);
   java.sql.Connection myConnection =
     dataSource.getConnection();

   //do what you wish with myConnection
 } catch (SQLException sqle) {
   getServlet().log("Connection.process", sqle);
 } finally {

   //enclose this in a finally block to make
   //sure the connection is closed
   try {
     myConnection.close();
   } catch (SQLException e) {
     getServlet().log("Connection.close", e);
   }
 }
}

Strutsジェネリックコネクションプールは、オプションのコンポーネントであることに気をつけてください。 多くのStrutsアプリケーションでは、特にハイボリュームのプロダクションシステムにおいては、他の適切なパフォーマンスのコネクションプールを利用しています。

Next: ビューコンポーネントの構築


[訳注: これは黒住 幸光が翻訳しました。日本語訳に対するコメントがあれば、report@jajakarta.orgに送って下さい。]
Copyright (c) 2000-2002, Apache Software Foundation