No Struts

Struts1.3のWebページ生成機構「Tiles」の使い方

2011年1月31日Apache Struts

本連載の内容は記事執筆当時のまま再公開しており、現在では古い、あるいは適切ではない内容を含んでいます。

ソリューション開発部の黒住です。

Webアプリケーションになくてはならない機能として、「Webページの生成」があります。この機能なくして、Webアプリケーションとは言えないでしょう。今回はStrutsアプリケーションにおけるWebページ生成を効果的に行う機能「Struts-Tiles」について紹介します。

Webアプリケーションはその性質上、Webブラウザが表示可能なWebページをアプリケーションの実行結果として返却する必要があります。このWebページ (プレゼンテーション) の生成のためにはさまざまなテクノロジがありますが、それぞれ一長一短です。Strutsが採用しているJSPについてもその採用には意見が分かれるところですが、J2EEの標準テクノロジであることを考えると、ベストとは言えないまでもベターな選択と言えるでしょう。本稿でも、このJSPを用いたWebページの生成を紹介します。

Struts-Tilesとは

Struts-Tiles とは複数のJSPページを、1枚のWebページとしてサーバーサイドで合成する機能です。Struts-TilesはStruts 1.1 から提供されるようになった機能ですがStruts1.3でも利用可能となっています。

Webページを設計する場合、下図のように、ページをヘッダ、メニュー、ボディー、フッタに分けたデザインをすることが多いはずです。

スクリーンショット:サンプルデザイン
図:サンプルデザイン

単純に考えると部位ごとのページを用意し、フレームによって1つのWebページとして表示する実装方法を思い浮かべるでしょう。しかし、フレームを用いて複数のJSPを合成する方法では、各部位のレイアウトをフレームとして管理するJSPが必要となり、場合によってはそのレイアウト用のページがWebページと同じ数だけできてしまいます。ボディー部に表示したいページとあわせると膨大な数のJSPを作成することになりかねません。またそのメンテナンスも容易ではありません。JSP のinclude機能を使うことによっても同様の機能を実現可能ですが、やはり前述のような問題が発生します。

そこで Struts では、Webページのレイアウト管理を行うフレームワーク Struts-Tiles を提供しています。

Struts-Tilesの機能を以下に示します。

  • ページ合成
    複数のJSPページが生成するコンテンツをサーバーサイドで合成して、1つのHTMLページとして生成します。
  • ページレイアウト管理
    複数JSPページの合成デザイン (レイアウト) をXMLファイルに定義します。レイアウトを継承して別のページを定義することもできます。モジュール設定ファイルでは、XMLファイルでページにつけた論理名をページに指定することになるため、実JSP名をモジュール設定ファイルから排除することが可能となります。
  • 動的なコンテンツ指定が可能
    静的にXMLファイルに定義したレイアウト情報以外にも、プログラム中からレイアウトやその中身であるコンテンツのJSPを動的に指定することも可能です。使い方によってはポータルサイトの構築が可能となります。

機能としては、レイアウト管理を行うだけのツールのため、非常にシンプルですが、その利用による効果は想像以上です。Struts-Tiles自身は、Struts1.3のディストリビューションにstruts-tiles-1.3.X.jar として含まれており、このjarファイルを WebアプリケーションのWEB-INF/lib ディレクトリに配置することで利用可能となります。

Struts-Tilesのしくみ

Struts-Tilesを利用するためには、jarファイルの配置とは別に、Struts-TilesプラグインをStrutsに組み込む必要があります。そして、プラグインにはページのレイアウトを定義したファイルを指定します。設定方法は後ほど説明します。Struts-Tilesを用いた場合のイメージを下に示します。

説明図:Struts-Tilesを用いた場合のイメージ
図:Struts-Tilesを用いた場合のイメージ

図からもわかるように、Struts-Tilesは各ページのレイアウト定義が記述されているファイル (本稿ではページ定義ファイルと呼びます) を参照して、その定義に従ってページの生成を行います。ページ定義ファイルには、生成するWebページに関して、どのJSPとどのJSPをどのレイアウトを用いて合成するかが定義されています。HTMLのフレームや、JSPのinclude機能を用いてページの合成を行う場合には、合成対象のJSP名がレイアウトと一体となり、ページごとにJSPを用意する必要があるためJSP数が増大します。また、JSP名がレイアウトファイル内に記述されるため、実JSP名がモジュール設定ファイル以外のファイルにも定義されることとなり、メンテナンス性が低下する危険性があります。Struts-Tilesでは、レイアウト (本稿ではレイアウト用JSPと呼びます) とコンテンツ (本稿ではコンテンツ用JSPと呼びます) を明確に分離して、両者を繋ぐ情報をページ定義ファイルで定義し、レイアウトに関する情報を集中管理することで、メンテナンス性の向上が図れます。また、レイアウト用JSPには実際に表示するコンテンツ用JSP名は定義しないため、レイアウトパターン数のみレイアウトファイルを用意すればよく、JSP数の大幅な削減が可能となるのです。

レイアウト用JSPの作成

実際に利用する場合には、各Webページの設計を綿密に行う必要があります。なぜなら、そのWebページを何と名づけ、どのようなレイアウトで何を配置するかを決定する必要があるからです。ただし、この各要素は、定義ファイルを作成するために必要なだけであり、変更は非常に容易なので、必ずしもすべてが正確に決定している必要はありません。これらの要素が決定したら、

  • レイアウト用JSPの作成
  • コンテンツ用JSPの作成 (ヘッダ用、フッタ用、ボディー用など)
  • ページ定義ファイルの作成

を行い、ページ定義ファイルをStruts-Tilesプラグインに指定します。

レイアウト用JSPの作成

用意する必要があるレイアウト用JSPは、ページのレイアウトパターン分だけです。すべてのページを同一のレイアウトパターンで表示する場合には、1つということです。例えば、先の「スクリーンショット:サンプルデザイン」のようなWebページを作成する場合、そのレイアウト用JSPは、「リスト:layout.jsp」のようになります。レイアウト用JSPは通常のコンテンツ用JSPとは異なり、テーブル関連のHTMLタグを用いてレイアウトを定義します。その際、各テーブルのセルにStruts-Tilesが提供する<tiles:insert>カスタムタグを用いて名前を付けます。ページ定義ファイルでは、この名前をキーにさまざまなコンテンツを結びつけるのです。「リスト:layout.jsp」では「スクリーンショット:サンプルデザイン」の通り header、menu、 body、 footer と各セルに名前をつけています。セルに名前をつける以外にもう1つ、ページのタイトルを動的に変化させるための処理を記述しています。通常、Webページはページごとにさまざまなタイトルをつけ、ページを識別しやすくする必要があるでしょう。このような場合、<tiles:getAsString>カスタムタグを利用します。これはページ定義ファイルに記述した文字列を、動的に挿入するためのカスタムタグです。例えば、同じレイアウト用JSPを利用した2つのページがあり、1つはページA、もう1つはページBというタイトルを表示したい場合に、ページA、ページBという文字列をページ定義ファイルに定義しておけば、各レイアウトにあったタイトルを表示することが可能となるのです (実際の文字列の定義方法は後述します)。

リスト:layout.jsp
リスト:layout.jsp

コンテンツ用JSPの作成 (1)

コンテンツ用の各JSPは、通常のJSPと同様に作成します。定常的に表示されるheader部、menu部、footer部は、「リスト:header.jsp」、「リスト:menu.jsp」、「リスト:footer.jsp」のように用意します。コンテンツ用JSPすべてに言えることですが、タイトルやhtmlタグなどはレイアウト用JSPに既に記述してあるため必要ありません。

リスト:header.jsp
リスト:header.jsp
リスト:menu.jsp
リスト:menu.jsp
リスト:footer.jsp
リスト:footer.jsp

コンテンツ用JSPの作成 (2)

ボディー部のコンテンツ用JSPはページの数分用意する必要がありますが、本稿では1つだけ紹介します (「リスト:shoplist.jsp」)。

リスト:shoplist.jsp
リスト:shoplist.jsp

以上で、必要なJSPはすべて揃ったことになります。

ページ定義ファイルの作成

ページ定義ファイルでは、前述のJSPを組み合わせて1つのページとして定義します。定義の方法は「リスト:tileDefinitions.xml」のように極めて単純です。1つのページ (合成後のWebページイメージ) は<definition>タグにてその内容を定義します。ページの論理名をname属性に定義して、レイアウト用JSPへのパスをpath属性に指定します。レイアウト内の各部 (headerやfooter) に実際のコンテンツ用JSPを割り当てるには、<put>タグをネストして定義します。<put>タグには部位名と割り当てるJSPへのパスを指定するだけです。すべての部位への割り当てが完了したものは、論理的なWebページとしてStruts-Tilesが認知し、モジュール設定ファイルにてこの論理名でWebページを指定できるようになります (指定方法は後述します)。また、文字列を動的にJSPに挿入するタグ<tiles:getAsString>カスタムタグのための文字列の指定は、この<definition>タグ単位で行います。定義方法はコンテンツ用JSPを指定した時と同様に <put>タグを用いてJSPへのパスの代わりに文字列を定義するだけです。

このStruts-Tilesのページ定義を行うしくみには、1つ強力な機能が備わっています。それが、レイアウトの継承です。「リスト:tileDefinitions.xml」のuser.shoplistの定義を参照してください。この定義にはtitleとbodyしか指定されていません。<definition>タグのpath属性を指定する代わりにextends属性が指定されています。extends属性はその名の通り、継承を示しています。要するにextendsで指定したページレイアウトを継承し、指定した部位のコンテンツのみを再定義しているのです。再定義されなかった部位は継承元の定義が引き継がれます。この機能により、ベースとなるページレイアウトを1つ定義し、実際に表示させるページはベースのレイアウトを継承し、titleやボディー部のみを再定義してゆけば、簡単にページを定義することができます。また、フッタやヘッダを変更する場合にも、ベースのレイアウト定義のみを変更すれば、継承しているページはすべて変更されるため、メンテナンス性が格段に向上します。Struts-Tilesの素晴らしい機能の1つです。

リスト:tileDefinitions.xml
リスト:tileDefinitions.xml

モジュール設定ファイルの記述

モジュール設定ファイルには通常、JSPへのパスを直接記述します。しかし、Struts-Tilesを用いた場合、JSPへのパスは、各ページの論理名として扱うことになります (「リスト:モジュール設定ファイル (struts-config.xml) 抜粋」)。Struts-Tilesを用いない場合、JSPへのパスを定義していたforwardタグ内のpath属性に、ページ定義ファイルの definitionタグで定義したページ名を指定しているのがお分かりいただけると思います。このようにして、各ページを指定していきましょう。

ここで1つ注意しなくてはならないことがあります。それは、このページ名はStruts-TilesプラグインすなわちStrutsのコントローラーを経由しないと有効にならないということです。ブラウザから直接この論理名のページを指定しても、表示することはできません。そのため、すべてのリクエストがコントローラーを経由するように、アプリケーション全体のページ遷移を設計する必要があります。最初のページ (通常、index.jspなど) にもStruts-Tilesを用いる場合は、コントローラーにリダイレクト処理などを行うようにする必要があります。

リスト:モジュール設定ファイル (struts-config.xml) 抜粋
リスト:モジュール設定ファイル (struts-config.xml) 抜粋

利用宣言と組み込み

Struts-Tilesの利用宣言

Struts-Tilesはその利用を宣言する必要があるとお話ししました。その方法を紹介します。定義方法は前述のようにプラグインをモジュール設定ファイルに追加するのみです。この時に「リスト:struts-config.xml抜粋」のように、ページ定義ファイルへのパスをpropertyとして指定します。

リスト:struts-config.xml抜粋
リスト:struts-config.xml抜粋

リクエスト処理手順へのTilesの組み込み

最後に、Struts1.3のHTTPリクエスト処理チェーンにStruts-Tilesが組み込まれるように、Tiles自身が用意しているチェーン定義を設定する必要があります。この定義は Webデプロイメントディスクリプタ (web.xml) のStrutsサーブレットへのパラメーターとして定義ファイルを指定します。具体的には、web.xml の action サーブレットの定義を下記のように指定することになります。

リスト:web.xmlのactionサーブレット定義
リスト:web.xmlのactionサーブレット定義

以上で、Struts-Tilesを用いたページが生成可能となります。準備に若干の手間がかかりますが、それ以上の効果が得られるはずです。

Struts-Tilesには、ご紹介した機能以外にもプログラム中から動的にレイアウトを変更する機能や定義する機能などが用意されています。この機能を用いることでポータルサイトを構築することも可能です。非常に強力なレイアウト機能を提供してくれるStruts-Tilesに興味のある方は、ぜひ利用してみてください。

※本稿は月刊JavaWorld (株式会社IDGジャパン発行) 2003年12月号に掲載した連載「Jakarta活用指南」記事の元原稿に加筆修正したものです。

  • 株式会社アークシステムの予約・来訪管理システム BRoomHubs
  • 低コスト・短納期で提供するまるごとおまかせZabbix