Web ベースのビジネス・アプリケーションではほとんどの場合、さまざまなデータベースにデータを保存する必要があります。Struts 2 の初心者にとって、Web アプリケーションを開発する際の最大の難題は、データベースに保存されたデータをブラウザーの表示ページにどう表示するか、という点にあります。
データ処理のための最適な手段を開発するためには多くの作業が必要になります。優れたアプリケーションには適切な UI (User Interface) と適切なバックエンド実装が必要です。Struts 2 の強力さは MVC (Model-View-Controller) パターンをすっきりと実装できる点にあり、それを実現しているのが以下の機能です。
- Action
- Action は Struts 2 フレームワークのアーキテクチャーの一部として、すべてのビジネス・ロジックを 1 ヶ所にまとめることで、簡潔な実装を実現します。Action はリクエストから結果ページにデータを自動転送するためのチャネルとして機能します。
- Result
- ユーザーの要求に対するアプリケーションの応答を Web ブラウザーに表示する UI です。
- Interceptor
- さまざまな Action で共通に行われる操作 (妥当性検証、ロギング命令、エラー・チェックなど) を実装することで、Action のオーバーヘッドをなくし、パフォーマンスを改善します。
Interceptor は処理前と処理後の両方で呼び出されます。1 つのアクション・リクエストに対し、複数の Interceptor がある場合があります。
- ValueStack
- リクエストの処理中に関連付けられるデータすべてを保持するオブジェクトです。
図 1 は Struts 2 フレームワークのコンポーネントを示しています。
図 1. Struts 2 の Action、Interceptor、Result
この記事では、Web ベースのアプリケーションでの動的なデータ処理について学びます。さらに、実行時にユーザー・データを送信する方法をいくつかの特別な使用ケースを例に探っていきます (例えばフォームにユーザー・データの値をあらかじめ入力する場合や、リストの中にある値からデフォルト値を表示するように UI フィールドを設定する場合など)。この記事では、Struts 2 の Action クラスと結果ページとの間での動的なデータのフローに関し、その実装の詳細に焦点を絞ります。
Struts 2 の ValueStack を使った動的なデータ処理
Struts 2 の強力な機能の 1 つである ValueStack は、リクエストを処理する際のすべてのデータを保持します。Action クラスも Bean の形でデータを保存します (Struts 2 ではゲッター・メソッドとセッター・メソッドを使います)。Action クラスのオブジェクトにデータが保存されると、Struts 2 はそのデータを、Action オブジェクトの形式で ValueStack に格納します。ValueStack は複数のオブジェクトを格納し、このデータが Struts 2 フレームワークの他の部分に公開されます。
図 2 では、Action クラスが 2 つの変数の値をゲッター・メソッドとセッター・メソッドを使って設定しています。このデータはリクエストが処理される間に、ValueStack に保存されます。HelloWorld.jsp はこれらの変数の値を ValueStack から取得し、Struts 2 のタグ・ライブラリーの <s:property> タグを使って表示します。
図 2. ValueStack に保持されるデータ
UI に表示されるデータが事前にわかる場合、そのデータは静的データと呼ばれます。静的データは、JSP (JavaServer Pages) で直接コーディングすることで、容易に処理することができます。図 3 は静的データの処理を示しています。
図 3. 静的データ
ユーザー・データベースから取得したデータをユーザーが表示しようとする場合、そのデータを Action と JSP で適切に処理して UI で表示するためのメカニズムが必要です。Struts 2 の場合、このタイプのシナリオのためのビルディング・ブロックは、Action クラスと ValueStack です。Action クラスはゲッター・メソッドとセッター・メソッドを使うことで、ユーザー値を ValueStack に格納します。すると、その値に対応する変数名の値を JSP が取得し、UI に表示します。図 4 を見てください。
図 4. 動的データ
Struts 2 にはリッチで再利用可能な HTML にデータを表示するタグ・ライブラリーがあるため、対話型でフォーム・ベースのアプリケーションを容易に作成することができます。Struts 2 には汎用タグ (制御タグとデータ・タグ) と UI タグが用意されています。UI タグは、ValueStack のデータ (ValueStack 上にある、アクションが追加されたデータ) またはデータ・タグのデータを取得するために設計されています。以下に示すのは Struts 2 の UI タグ <select tag> の例です。
- UI にデータを表示するための
Actionクラスを作成します (リスト 1)。
リスト 1. UI にデータを表示するためのActionクラスを作成するpublic class DisplayAction extends ActionSupport { private List state = new ArrayList(); private List status = new ArrayList(); public String execute() { setState(this.state); setStatus(this.status); return "success"; } //getter and setter method for state variable// public List getState() { return state; } public void setState(List state) { //implement the application specific logic to retrieve the data from the database here// //Here for displaying the data on UI, we are using few hardcoded values// state.add("Defect"); state.add("Task"); state.add("User Stories"); } public List getStatus() { return status; } public void setStatus(List status) { //implement the application specific logic to retrieve the data from the database here// //Here for displaying the data on UI, we are using few hardcoded values// status.add("New"); status.add("Fixed") status.add("Resolved"); status.add("Closed"); } }
この例では
DisplayActionクラスが、ArrayListオブジェクトの state と status に値をいくつか設定しています。Actionクラスはこのデータを ValueStack に格納し、JSP はそのデータを UI に表示します。 - JSP 側でデータを処理するために、
stateとstatusの値を取得する <select> タグを作成する必要があります (リスト 2)。
リスト 2.stateとstatusの値を取得する <select> タグを作成する<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib prefix="s" uri="/struts-tags" %> <html> <title>Sample Display Page</title> <body> <s:select list="%{status}" name="Status"></s:select> <s:select list="%{state}" name="State"></s:select> </body> </html>
- struts.xml によるマッピングを使って
Actionと JSP を構成します (リスト 3)。
リスト 3. struts.xml によるマッピングを使ってActionと JSP を構成する<!DOCTYPE struts PUBLIC"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="sample.exmaple" extends="struts-default"> <action name=”DisplayAction” class=”com.sample.example.DisplayAction”> <result name=”success”>/DisplayPage.jsp </result> </action> </package> </struts>
上記 3 つのコード例は、以下のようになっています。
Actionクラスにstateとstatusというリスト変数があります。stateとstatusをarraylist型にすることで、Actionクラスにデータを追加しています。<s:select>には、Action クラスの中で定義された名前と同じ名前を持つリスト・パラメーター (必須) があります。- これらのリスト変数を
%{<list-variable>}を使って配置しています。 - JSP の中のリスト変数の名前は、
Actionクラスの中で指定された名前と一致しなければなりません。
図 5 は出力の例を示しています。
図 5. 出力 1: Status リストの表示
図 6 では、Status という <select> タグが、Action クラスに入力された値で初期化されています。
図 6. 出力 2: State リストの表示
また、State という <select> タグも、Action クラスに入力された値で初期化されています。
ここで例えば、ユーザーが値のリストを持っているとします。ユーザーは、UI がロードされたら、リストの中にある値の 1 つをデフォルト値に設定したいと思っています。
以下の例では、ユーザーはコンボ・ボックスを持っており、UI がロードされたら最後の値を表示したいと思っています。
Actionクラスを変更し、デフォルト値のコードを追加します (リスト 4)。
リスト 4.Actionクラスを変更し、デフォルト値のコードを追加するpublic class DisplayAction extends ActionSupport { private List state = new ArrayList(); private List status = new ArrayList(); private String defaultState = ""; private String defaultStatus = ""; public String execute() { //set status and state list values// setState(this.state); setStatus(this.status); //set default values for state and status which //a user wants to display on the User Interface setDefaultState("Task"); setDefaultStatus("Closed"); return "success"; } //getter and setter method// public List getState() { return state; } public void setState(List state) { //implement the application specific logic to retrieve //the data from the database here// //Here for displaying the data, we are using few //hardcoded values state.add("Defect"); state.add("Task"); state.add("User Stories"); } public List getStatus() { return status; } public void setStatus(List status) { //implement the application specific logic to retrieve //the data from the database here// //Here for displaying the data, we are using few //hardcoded values// status.add("New"); status.add("Fixed"); status.add("Resolved"); status.add("Closed"); } public String getDefaultState() { return defaultState; } public void setDefaultState(String defaultState) { this.defaultState = defaultState; } public String getDefaultStatus() { return defaultStatus; } public void setDefaultStatus(String defaultStatus) { this.defaultStatus = defaultStatus; } }
この例では上記の
Actionクラスの中で、さらに 2 つのゲッター/セッター・メソッドを追加し、<select>タグの変数にデフォルト値を設定しています。- 変更された JSP のコードを以下のリスト 5 に示します。
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib prefix="s" uri="/struts-tags" %> <html> <title>Sample Display Page</title> <body> <s:select list="%{status}" name="Status" value="%{defaultStatus}"></s:select> <s:select list="%{state}" name="State" value="%{defaultState}"></s:select> </body> </html>
この場合は struts.xml によるマッピングは先ほどと同じままです。
上記 2 つのコード例は、以下のようになっています。
Actionクラスの中で、表示されるデフォルト値は 2 つのストリング変数に保存されます。- JSP の中で、これらの値は
<select>タグのvalueパラメーターを使って処理されます。 Actionクラスの中でデフォルト値を持つ変数の名前は、結果を表示する JSP の中にある名前と一致しなければなりません。
図 7 は出力の例を示しています。
図 7. 出力 1: 「Status」のデフォルト値の表示
図 8 では、UI がロードされた時の「Status」リストのデフォルト値として、「Closed」が設定されています。
図 8. 出力 2: 「State」のデフォルト値の表示
UI がロードされた時の「State」リストのデフォルト値としては、「Task」が設定されています。
Struts 2 は第 2 世代の Web アプリケーション・フレームワークであり、Java サーブレットよりもよく使われるようになっています。Struts 2 は、よく使われる MVC デザイン・パターンに対応しています。Struts 2 によって一般的なタスクが自動化されるため、Action から結果ページへのマッピングを SML ベースの構成を利用して行えるようになります。Struts 2 フレームワークは Web ベースのアプリケーションの実装に関する基本部分の詳細をカバーしており、また構造的なソフトウェアを提供しています。
この記事では、完全なフレームワークとしての Struts 2 の機能について学びました。そして Struts 2 の最も一般的な使用ケースをいくつか学び、Struts 2 の強力な機能によって実現されるソリューションについて説明しました。
学ぶために
- Java Web アプリケーションを作成するための無料のオープンソース・フレームワーク、Apache Struts 2 を理解してください。
- Struts 2 のドキュメントを見てください。このサイトには、入門者用資料、チュートリアル、FAQ、ガイドなどが用意されています。
- ValueStack の資料を読んでください。ValueStack に複数の Bean をプッシュすることができ、また ValueStack に対して動的な EL 式を評価することができます。
- Struts 2 の UI タグ参照を利用してください。Strut の UI タグによって、リッチで再利用可能な HTML にデータを表示することができます。
- Struts 2 のドキュメントその他の資料を入手してください。セキュリティー報告、ウィキ、クイック・リンク、チュートリアルなどがあります。
- developerWorks の Web development ゾーンには、Web ベースの多様なソリューションを網羅した記事が豊富に用意されています。
- developerWorks の Technical events and webcasts で最新情報を入手してください。
- developerWorks On demand demos をご覧ください。初心者のための製品インストール方法やセットアップのデモから、上級開発者のための高度な機能に至るまで、多様な話題が解説されています。
製品や技術を入手するために
- 皆さんの目的に最適な方法で IBM 製品を評価してください。製品の試用版をダウンロードする方法、オンラインで製品を試す方法、クラウド環境で製品を使う方法、あるいは SOA Sandbox で数時間を費やし、サービス指向アーキテクチャーの効率的な実装方法を学ぶ方法などがあります。
議論するために
- My developerWorks で開発者向けのブログ、フォーラム、グループ、ウィキなどを利用しながら、他の developerWorks ユーザーとやり取りしてください。
