Tilesによる画面レイアウト ================================================================================ .. only:: html .. contents:: 目次 :depth: 3 :local: Overview -------------------------------------------------------------------------------- | ヘッダ、フッタ、サイドメニューといった共通的なレイアウトを持つWebアプリケーションを開発する場合に、全てのJSPに共通部分をコーディングすると、メンテナンスが煩雑になる。 | 例えば、ヘッダのデザインを修正する必要がある場合、全てのJSPに修正を加えなければならない。 | JSPでの開発で多くの画面で同じレイアウトを使用する場合は、 `Apache Tiles `_\ (以下、Tiles)の利用を推奨する。 | 理由は、以下3つの通りである。 #. 設計者によるレイアウトの誤差をなくすこと #. 冗長なコードを減らすこと #. 大きなレイアウトの変更が容易になること | Tilesは、統一的な画面レイアウトの際に定義を行うことで、別々のJSPを組み合わせることができる。 | その結果、各々のJSPファイルに、余計なコードを記述することがなくなるため、開発者の作業を楽にできる。 | 例えば、下記のようなレイアウト構成が複数の画面に存在する場合、 .. figure:: ./images/screen_layout.png :alt: screen layout :width: 50% :align: center **Picture - Image of screen layout** | Tilesを使用することにより、同じレイアウトの全ての画面でheaderやmenu、footerをincludeしてサイズを指定することなく、bodyの作成のみに集中することができる。 | 実際のJSPファイルは下記のようになる。 .. figure:: ./images/layout_jsp.png :alt: layout jsp :width: 50% :align: center **Picture - Image of layout jsp** よって、Tilesで画面レイアウトを設定した後は、業務に相当するJSPのみ(buisness.jsp)画面毎に作成すればよい。 .. note:: Tilesの適用をしない方がよい場合もある。例えば、エラー画面にTilesを使用するのは、以下の理由により推奨しない。 * エラー画面表示中にTilesによるエラーが発生すると解析がしにくくなるため。(二重障害発生の場合) * web.xmlのタグで設定するJSPでは、必ずしも画面表示にTilesによるテンプレートが適用されないため。 | .. _TilesLayoutHowToUse: How to use -------------------------------------------------------------------------------- pom.xmlの設定 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | TilesをMavenで使用する場合、以下のdependencyをpom.xmlに追加する必要がある。 .. code-block:: xml org.terasoluna.gfw terasoluna-gfw-recommended-web-dependencies pom .. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 * - 項番 - 説明 * - | (1) - | webに関連するライブラリ群が定義してあるterasoluna-gfw-recommended-web-dependenciesをdependencyに追加する。 * - | (2) - | terasoluna-gfw-recommended-web-dependenciesは依存関係が定義してあるpomファイルでしかないため、 | ``pom`` の指定が必要である。 | .. note:: 上記設定例は、依存ライブラリのバージョンを親プロジェクトである terasoluna-gfw-parent で管理する前提であるため、pom.xmlでのバージョンの指定は不要である。 | Spring MVCとTilesの連携 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | Spring MVCとTilesを連携するには ``org.springframework.web.servlet.view.tiles3.TilesViewResolver`` を利用すればよい。 | Spring MVCのControllerの実装(View名の返却)を変更する必要は無い。 設定方法について、以下に示す。 **Beanの定義(ViewResolver、TilesConfigurer)** - spring-mvc.xml .. code-block:: xml .. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 * - 項番 - 説明 * - | (1) - \ ````\ 要素を使用して、\ ``TilesViewResolver``\ を定義する。 \ ````\ 要素より上に定義することで、最初にTiles定義ファイル(:file:`tiles-definitions.xml`)を参照して\ ``View``\を解決するようにする。 Controllerから返却されたView名が、Tiles定義ファイル内の\ ``definition``\ 要素の\ ``name``\ 属性のパターンに合致する場合、\ ``TilesViewResolver``\ によって\ ``View``\が解決される。 * - | (2) - \ ````\ 要素を使用して、JSP用の\ ``InternalResourceViewResolver``\ を定義する。 \ ````\ 要素より下に定義することで、\ ``TilesViewResolver``\で解決できなかったView名のみ、JSP用の\ ``InternalResourceViewResolver``\を使用して\ ``View``\を解決するようにする。 View名に対応するJSPファイルが、\ ``/WEB-INF/views/``\ 配下に存在する場合、JSP用の\ ``InternalResourceViewResolver``\ によって\ ``View``\が解決される。 * - | (3) - \ ````\ 要素を使用して、Tiles定義ファイルを読み込む。 \ ````\ 要素の\ ``location``\ 属性に、Tiles定義ファイルを指定する。 **Tilesの定義** - tiles-definitions.xml .. code-block:: xml .. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 * - 項番 - 説明 * - | (1) - | tilesのdtdを定義する。 * - | (2) - | レイアウト構成の親定義。 | template属性には、レイアウトを定義しているjspファイルを指定する。 * - | (3) - | headerを定義しているjspファイルを指定する。 * - | (4) - | footerを定義しているjspファイルを指定する。 * - | (5) - | 描画の際にControllerから返却されたView名がnameのパターンと同じ場合に呼ばれるレイアウト定義。 | extendsしている layouts定義も適用される。 * - | (6) - | タイトルを指定する。 | valueはspring-mvcに取り込まれているpropertiesの中から取得する。(以下の説明では application-messages.propertiesに設定する。) | {1},{2}はControllerから返却されたView名の"\*/\*"の「*」の1つ目、2つ目に該当する。 * - | (7) - | bodyを定義しているjspファイルの置き場所について、{1},{2}にControllerから返却されたView名の"\*/\*"の「*」の1つ目、2つ目が一致するように設計する。これにより、Controllerから返却されるView名ごとの定義を記述する手間を省くことができる。 .. note:: Tilesの適用をしたくない画面(エラー画面等)の場合、Tiles使用対象にならないようなファイル構成にする必要がある。 ブランクプロジェクトでは、エラー画面に InternalResourceViewResolverが使われるように("\*/\*"形式にならないように)、 /WEB-INF/views/common/error/xxxError.jsp形式にしている。 - `application-messages.properties` .. code-block:: properties title.staff.createForm = Create Staff Information .. note:: メッセージプロパティファイルの記載方法については、 :doc:`../WebApplicationDetail/MessageManagement` を参照されたい。 Tilesを設定したときのファイル構成を以下に示す。 - tiles File Path .. figure:: ./images/tiles_filepath.png :alt: tiles file path **カスタムタグの設定** Tilesを使用するためにカスタムタグ(TLD)を設定する必要がある。 - /WEB-INF/views/common/include.jsp .. code-block:: jsp <%@ page session="false"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%> <%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%> <%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%> <%@ taglib uri="http://www.springframework.org/security/tags" prefix="sec"%> <%@ taglib uri="http://terasoluna.org/functions" prefix="f"%> <%@ taglib uri="http://terasoluna.org/tags" prefix="t"%> <%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%> <%@ taglib uri="http://tiles.apache.org/tags-tiles-extras" prefix="tilesx"%> .. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 * - 項番 - 説明 * - | (1) - | Tiles用のカスタムタグ(TLD)の定義を追加する。 * - | (2) - | Tiles-extras用のカスタムタグ(TLD)の定義を追加する。 Tilesのカスタムタグの詳細は、\ `こちら `_\ を参照されたい。 .. tip:: | version 2系では tiles taglib は一つであったが、version 3から tiles-extras taglib が追加された。 | version 2系では tiles taglib で利用可能であった useAttribute tag がversion 3から tiles-extras taglib へ移動されているので、利用していた場合は注意すること。 | 変更例 ) `` : version 2 -> `` : version 3 - web.xml .. code-block:: xml *.jsp false UTF-8 false /WEB-INF/views/common/include.jsp .. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 * - 項番 - 説明 * - | (1) - | web.xmlの設定で、jspファイル(~.jsp)を読み込む場合、事前にinclude.jspを読み込ませることができる。 .. note:: カスタムタグはtemplate.jspに設定しても問題は無いが、カスタムタグの定義はインクルード用の共通jspファイルに作成することを推奨する。 詳細は :ref:`view_jsp_include-label` を参照されたい。 **レイアウト作成** レイアウトの枠となるjsp(template)と、レイアウトに埋め込むjspを作成する。 - template.jsp .. code-block:: xml <spring:message code="${titleKey}" text="Create Staff Information" />
.. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 * - 項番 - 説明 * - | (1) - | 共通的に記述する必要のある内容を(1)より上に記述する。 * - | (2) - | tiles-definitions.xmlの(6)で指定した ``title`` の値を取得し、 ``titleKey`` に設定する。 * - | (3) - | タイトルを設定する。 | ``titleKey`` が取得できなかった際は、text属性で定義したタイトルを表示する。 * - | (4) - | tiles-definitions.xmlで定義した"header"を読み込む。 * - | (5) - | tiles-definitions.xmlで定義した"body"を読み込む。 * - | (6) - | tiles-definitions.xmlで定義した"footer"を読み込む。 - header.jsp .. code-block:: jsp

Staff Management System

- createForm.jsp(body部分の例) 開発者は、headerやfooterの余分なソースを記述せずに、body部分のみに集中して記述できる。 .. code-block:: jsp

Create Staff Information

Staff First Name
Staff Family Name
Staff Authorities Staff Management
Master Management
Stock Management
Order Management
Show Shopping Management
- footer.jsp .. code-block:: jsp

Copyright © 20XX CompanyName

.. note:: フッターに記載する著作権に関しては :ref:`CreateWebApplicationProjectCustomizeCopyrightOnScreenFooter` を参照すること。 **Controller作成** ControllerからView名として"staff/createForm"を返却する。 - StaffCreateController.java .. code-block:: java @RequestMapping(value = "create", method = RequestMethod.GET, params = "form") public String createForm() { return "staff/createForm"; // (1) } .. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 * - 項番 - 説明 * - | (1) - | staffが{1}、createFormが{2}となり、propertiesからタイトル名を取得し、JSPを特定する。 **画面描画** View名に"staff/createForm"が指定されると、 以下のようにTilesがレイアウトを構築して画面描画を行う。 .. code-block:: xml .. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 * - 項番 - 説明 * - | (1) - | 該当するView名が指定された時、親レイアウトである layouts が呼ばれ、テンプレートが /WEB-INF/views/layout/template.jspに設定される。 * - | (2) - | テンプレート /WEB-INF/views/layout/template.jsp内に存在する ``header`` に WEB-INF/views/layout/header.jspが設定される。 * - | (3) - | テンプレート /WEB-INF/views/layout/template.jsp内に存在する ``footer`` に /WEB-INF/views/layout/footer.jspが設定される。 * - | (4) - | staffが{1}、createFormが{2}となり、spring-mvcに取り込まれているpropertiesから ``title.staff.createForm`` をkeyにvalueを取得する。 * - | (5) - | staffが{1}、createFormが{2}となり、テンプレート/WEB-INF/views/layout/template.jsp内に存在する ``body`` に/WEB-INF/views/staff/createForm.jspが設定される。 結果として上記のtemplate.jspに、header.jsp、createForm.jsp、footer.jspが組み合わされた方法でブラウザに出力される。 .. figure:: ./images/tiles_result.png :alt: tiles result :width: 100% :align: center | How to extend -------------------------------------------------------------------------------- 複数レイアウトを設定する場合 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | 実際に業務アプリケーションを作成する場合、業務内容によって表示レイアウトを分けたい場合がある。 | 今回は、スタッフ検索機能の場合、メニューを画面の左側に出す要望があると想定する。 | その設定方法について、 :ref:`TilesLayoutHowToUse` をベースに以下に示す。 **Tilesの定義** - tiles-definitions.xml .. code-block:: xml :emphasize-lines: 7-20 .. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 * - 項番 - 説明 * - | (1) - | 今回追加するレイアウト構成の親定義。 | 別のレイアウトを使用する場合、difinitionタグのname属性について、既存のレイアウト定義"layouts"と重複しないようにする。 * - | (2) - | 今回追加するレイアウトについて、描画の際にControllerから返却されたView名がnameのパターンと同じ場合に呼ばれるレイアウト定義。 | View名が"\*/search\*"に該当する場合、このレイアウト定義が読み込まれる。 | extendsしている レイアウト定義"layoutsOfSearch"も適用される。 * - | (3) - | 今回追加するレイアウトで使用するタイトルを指定する。 | valueはspring-mvcに取り込まれているpropertiesの中から取得する。(以下の説明では application-messages.propertiesに設定する。) | {1}はControllerから返却されるView名の"\*/search\*"の「\*」の1つ目、"search{2}"はView名の"\*/search\*"の"search\*"に該当する為、先頭が"search"で始まる必要がある。 * - | (4) - | bodyを定義しているjspファイルの置き場所について、{1}にControllerから返却されるView名の"\*/search\*"の「\*」の1つ目、"search{2}"はView名の"\*/search\*"の"search\*"であるため、先頭に"search"を含んだJSPファイル名が一致するように設計する。 | JSPファイルの置き場所の構成によってvalue属性の値を変更する必要がある。 .. note:: Controllerから返却されるView名がdefinitionタグのname属性のパターンに複数該当する場合、上から順に確認し、1番最初に該当するパターンが採用される。 上記の場合、スタッフ検索画面のView名が、definitionタグのname属性のパターンに複数該当するため、1番上にレイアウト定義している。 - `application-messages.properties` .. code-block:: properties :emphasize-lines: 2 title.staff.createForm = Create Staff Information title.staff.searchStaff = Search Staff Information # (1) .. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 * - 項番 - 説明 * - | (1) - | 今回追加するメッセージ。 | "staff"はControllerから返却されたView名の"\*/search\*"の「*」の1つ目。 | "searchStaff"はControllerから返却されたView名の"\*/search\*"の"search\*"に該当する為、先頭が"search"で始まる必要がある。 **レイアウト作成** レイアウトの枠となるjsp(template)と、レイアウトに埋め込むjspを作成する。 - templateSearch.jsp .. code-block:: xml <spring:message code="${titleKey}" text="Search Staff Information" />
.. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 * - 項番 - 説明 * - | (1) - | tiles-definitions.xmlで定義した"menu"を読み込む。 | それ以外は :ref:`TilesLayoutHowToUse` と同じ - styles.css .. code-block:: css div#menu { /* (1) */ float: left; width: 20%; } div#searchBody { /* (2) */ float: right; width: 80%; } div#footer { /* (3) */ clear: both; } .. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 * - 項番 - 説明 * - | (1) - | menu部分のstyleを設定する。 | ここでは、float:leftでメニュー画面を左側に寄せて、width:20%として横幅2割で表示をするようにしている。 * - | (2) - | body部分のstyleを設定する。 | ここでは、float:rightで業務画面を右側に寄せて、width:80%として横幅8割で表示をするようにしている。 | 名前をsearchBodyにしているのは、既存のレイアウトと名前が重複することにより、既存のレイアウトのstyleに影響を与えないためである。 * - | (3) - | footer部分のstyleを設定する。 | 上記menu部分とbody部分のfloatの効果を初期化している。これにより、menu部分とbody部分の下に表示するようにしている。 - header.jsp :ref:`TilesLayoutHowToUse` と同じ - menu.jsp .. code-block:: jsp
Create Staff Information
Search Staff Information
- searchStaff.jsp(body部分の例) .. code-block:: jsp

Search Staff Information

Staff First Name
Staff Family Name
Staff Authorities Staff Management
Master Management
Stock Management
Order Management
Show Shopping Management
- footer.jsp :ref:`TilesLayoutHowToUse` と同じ **Controller作成** ControllerからView名として"staff/searchStaff"を返却する。 - StaffSearchController.java .. code-block:: java @RequestMapping(value = "search", method = RequestMethod.GET) public String createForm() { return "staff/searchStaff"; // (1) } .. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 * - 項番 - 説明 * - | (1) - | staffが{1}、searchStaffが{2}となり、propertiesからタイトル名を取得し、JSPを特定する。 **画面描画** View名に"staff/searchStaff"が指定されると、 以下のように別のレイアウトを構築して画面描画を行う。 .. code-block:: xml .. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 * - 項番 - 説明 * - | (1) - | 該当するView名が指定された時、親レイアウトであるlayoutsOfSearchが呼ばれ、テンプレートが /WEB-INF/views/layout/templateSearch.jspに設定される。 * - | (2) - | テンプレート /WEB-INF/views/layout/templateSearch.jsp内に存在する ``header`` に WEB-INF/views/layout/header.jspが設定される。 * - | (3) - | テンプレート /WEB-INF/views/layout/templateSearch.jsp内に存在する ``menu`` に /WEB-INF/views/layout/menu.jspが設定される。 * - | (4) - | テンプレート /WEB-INF/views/layout/templateSearch.jsp内に存在する ``footer`` に /WEB-INF/views/layout/footer.jspが設定される。 * - | (5) - | Controllerから返却されたView名が"\*/search\*"に該当する場合、このレイアウト定義が読み込まれる。 | その時、親レイアウトである"layoutsOfSearch"も読み込まれる。 * - | (6) - | staffが{1}、searchStaffが"search{2}"となり、spring-mvcに取り込まれているpropertiesから ``title.staff.searchStaff`` をkeyにvalueを取得する。 * - | (7) - | staffが{1}、searchStaffが"search{2}"となり、テンプレート/WEB-INF/views/layout/templateSearch.jsp内に存在する ``body`` に/WEB-INF/views/staff/searchStaff.jspが設定される。 結果として上記のtemplateSearch.jspに、header.jsp、menu.jsp、searchStaff.jsp、footer.jspが組み合わされた方法でブラウザに出力される。 .. figure:: ./images/tiles_result2.png :alt: tiles result another template :width: 100% :align: center .. raw:: latex \newpage