図5●サンプル「nikkei.war」に含まれるファイル(抜粋)
図5●サンプル「nikkei.war」に含まれるファイル(抜粋)
[画像のクリックで拡大表示]
リスト1 ●Struts の諸機能を有効化するためにデプロイメント・ディスクリプタ(web.xml )に記述する内容
リスト1 ●Struts の諸機能を有効化するためにデプロイメント・ディスクリプタ(web.xml )に記述する内容
[画像のクリックで拡大表示]
リスト2 ●アクション・クラスUpdateAction のread メソッド
リスト2 ●アクション・クラスUpdateAction のread メソッド
[画像のクリックで拡大表示]

設定ファイルとクラスの構成を理解する

 それではサンプルの中身を見ていきましょう。nikkei.warは,Webアプリケーションに必要なリソースを一つにまとめたwar(Web Application Resources)ファイルになっています。この中に,必要なStrutsのファイルと外部ライブラリとして利用したJSTL(JSP Standard Tag Library)のファイルも含まれています*5

 Strutsを利用したアプリケーションの構造を知るため,warファイルに含まれるファイルを見てみましょう(図5[拡大表示])。warファイルの実体はzipファイルであり,jarコマンドを使うか拡張子をzipに変えることで解凍できます。

 まず,Strutsの諸機能を有効にするには,JSP&サーブレット標準の設定ファイルである「web.xml」(デプロイメント・ディスクリプタ)を編集する必要があります(リスト1[拡大表示])。web.xmlはWEB-INFフォルダに配置します。

 <servlet>要素と<servlet-mapping>要素は,サーブレットを登録するための設定要素です(リスト1(1))。サンプルでは,Strutsの実行エンジンであるアクション・サーブレットを有効にしています。これにより,拡張子「.do」で呼び出されたリクエストはすべてアクション・サーブレットで処理されるようになります。

 <taglib>要素は,タグ・ライブラリの登録を行うものです(リスト1(2))。StrutsではJSPページで利用可能なタグ・ライブラリをいくつか提供しています。サンプルでは,その中でよく利用すると思われるBeanやHTMLといったタグ・ライブラリを登録しています。Beanタグ・ライブラリはJavaBeansを操作/参照するためのものであり,HTMLタグ・ライブラリはHTMLベースのユーザー・インタフェースを生成するためのものです。

 アクション・サーブレットの動作を定義する設定ファイルはstruts-config.xmlです。アクション・サーブレットはこのファイルの内容に従って,リクエストされたURLに応じて処理をアクション・クラスに割り振ったり,処理の結果を適切なJSPページに渡します。

 サンプルでアクション・クラスに相当するのはUpdateActionクラスです。注意していただきたいのは,「アクション・クラスには原則としてビジネス・ロジックを記述すべきではない」ということです。あくまで,アクション・クラスにはアクションの振り分けを行う役割だけを持たせ,ビジネス・ロジックはアクション・クラスが呼び出すJavaBeans(サンプルではArticleクラス)に記述するようにしてください。アクション・クラスにデータベース・アクセスなど複雑なコードを記述するのは,アプリケーションの保守性を著しく低下させる原因になります。

アクション・クラスが返すのは処理結果ではなくステータス

 次にアクション・クラスの内容を見ていきましょう。UpdateActionのreadメソッド(リスト2)は,JavaBeansクラスArticleのgetInfosメソッドを呼び出し,その戻り値をリクエスト属性「Article.List」に登録するだけの単純なメソッドです*6。Article#getInfosメソッドは,MySQL上のdiaryテーブルの内容を登録日の降順に取り出し,Articleオブジェクトの配列(ArrayListオブジェクト)として返します。コードの詳細は実際のサンプルを参照していただくとして,ここではアクション・クラスに特有のルールについて押さえておくことにしましょう。

 Strutsを利用する開発者がアクション・クラスを記述する場合,気をつけるべき点は大きく二つあります。まず,アクション・クラスは必ずActionクラス(またはそのサブクラス)を継承しなければなりません。Actionクラスはアクション・サーブレットと通信するために必要な一連の機能を備えたクラスです。Actionクラスを継承することで,開発者はStruts内部のデータのやり取りをほとんど意識せず,ビジネス・ロジックの記述に集中できるというわけです。

 今回のサンプルでは,ActionクラスのサブクラスであるMappingDispatchActionクラスを利用しています。Struts 1.2から追加されたクラスです。Actionクラスは一つのクラスで一つのアクションしか扱えないのに対し,MappingDispatchActionクラスは「検索」「挿入」「更新」「削除」といった関連する複数のアクションを一つのクラスで記述できるのが特徴です。Actionクラスをそのまま利用するのに比べて,アプリケーション内のクラス数を抑えることができます。

 MappingDispatchActionクラスを継承するクラスでは,以下のようなシグニチャを持った実行メソッドを一つ以上定義する必要があります。

public ActionForward メソッド名
(ActionMapping map,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)

メソッド名は,後述するstruts-config.xmlで指定したパラメータ値と対応していれば,どのような名前を付けても構いません*7。引数として,処理の関連付けを管理するActionMappingオブジェクト,入力データを保持するActionFormオブジェクト,JSP&サーブレットをご存じの方ならばおなじみのHttpServletResponse/HttpRequestオブジェクトを渡します。実行メソッドの中身には,アクション・クラスが呼び出されたタイミングで実行するコードを記述します。

 もう一つの注意点は,アクション・クラスの実行メソッドは,戻り値として処理結果そのものではなく,結果ステータス(リスト2[拡大表示]の例ではsuccess)を返さなければならないということです。例えば,アクション・クラスで「10+5」という演算を行った場合,実行メソッドの戻り値は15ではありません。処理結果そのものはリクエスト属性にセットしておき,加算に成功したという「状態」を返す必要があります。


山田 祥寛(やまだ よしひろ)

千葉県鎌ヶ谷市在住のフリーライター(http://www.wings.msn.to/