StrutsによるWebアプリケーション開発

2003/04/04 更新
インフォサイエンス株式会社
稲村 大介 <inamura@infoscience.co.jp>

目次

はじめに
Strutsとは
Strutsを使うメリット
Struts の仕組み
開発の実際
struts-config.xml の編集
JSP の編集
アクションフォームビーンの作成
アクションクラスの作成
・タグライブラリ
bean タグライブラリ
html タグライブラリ
logic タグライブラリ
template タグライブラリ
開発における注意点
Struts 関連ツール
情報源

はじめに

現在、Webアプリケーション開発においてフレームワークは必須の存在となっている。
各社使用するフレームワークは様々だが、享受したいと考えるメリットは共通している。 まず、アプリケーションを開発するに当たり、そのアーキテクチャやクラス間の連携方法など検討する必要がある。 しかし、Webアプリケーションにおいてその仕組みはほぼ同じである為、アプリケーション毎に同じような仕組みを何度も設計・開発するのは避けたい。
フレームワークはこの問題を解決する。フレームワームは共通するアーキテクチャを抽象化し、再利用可能な形で提供される為、開発効率を向上させる事ができる。 フレームワークにはオープンソースで提供されているもの、有償で販売されているもの等数多く存在するが、中でも Jakarta Project の オープンソースフレームワークである Struts が最近注目されている。 Struts はシンプルだが非常に強力なフレームワークであり、導入事例も多く、情報が豊富である。
本稿では、主に Struts を使用した際のメリットや注意点について解説し、細部には踏み込まない。細部については 情報源 を参照して頂きたい。

Strutsとは

Strutsとは、Jakarta Project によって開発されている、Java Servlet/JSP 技術を用いたWebアプリケーション開発を行う上で有用な、オープンソースフレームワークである。 100% Pure Java で記述されており、ほぼ全てのサーブレットコンテナでの動作が確認されている。私が過去に参加したプロジェクトでは Struts と組み合わせて、Tomcat、WebSphere、iPlanet 等のサーブレットコンテナを使用したが、いずれも問題なく動作した。
また、Struts をベースとしたフレームワークも幾つか開発されており、代表的なものとしては 日本IBM の「Extension for Struts」等がある。

Struts の2003年4月現在の最新バージョンは 1.0.2 である。本稿では、このバージョン 1.0.2 を対象に解説を行う。(1.1 は現在 RC1 で、リリース間近)

Strutsを使うメリット

Struts を使うことにより得られるメリットは多いが、その中でも以下が重要である。
・開発効率が向上する
Webアプリケーション開発につきもののリクエストデータの取得や再表示時のデータの復元等は、Struts が行ってくれる。 Struts に慣れるまである程度(開発者によって異なるが 2 〜3週間)の時間は必要になるが、開発効率は確実に向上する。

・作業分担が容易になる
これは Struts のメリットというよりも MVC モデルのメリットだが、Model / View / Controller それぞれの結合が弱いため、作業の分担が容易となる。 ロジック(Model)を作る人、デザイン(View)を作る人、画面遷移(Controller)を作る人、等のような分担が可能である。

・画面デザインの変更に強い
これも MVC モデルのメリットだが、画面デザインの変更が発生した場合でも Model や Controller の修正は不要であり、View である JSP の修正だけで済む。

・一定の品質を保てる
Struts はフレームワークであり、動作の流れを規定している。開発者はその流れの上で必要なパーツを埋めていくという作業になる為、 開発者によって作り方が大きく違う、といった事態を防ぐ事ができる。

・国際化対応が容易
Struts ではリソースバンドルを利用したマルチリンガルに対応している為、各国語用のリソースファイルを用意するだけでクライアントの環境に応じたコンテンツを表示することができる。
・柔軟な画面遷移が実現できる
画面遷移情報を全て設定ファイル(struts-config.xml)に持つ為、複雑になりがちな画面遷移処理を容易に記述する事ができる。

・JSP の可読性が向上する
標準で用意されているタグライブラリを利用する事によりJSPの記述に一貫性を持たせることができ、スクリプトレット等を埋め込む事による可読性の低下を防ぐ事が可能になる。

・教材として学習に利用できる
公開されているソースを読む事により、Servletの基本動作、MVC モデルを理解する事ができる。

 



開発における注意点

Struts を用いた開発には、幾つか注意しなければならない事がある。開発を始める前に、以下について検討が必要になるだろう。
・自由度が高い
Struts は比較的自由度の高いフレームワークである。その為、ビジネスロジックを記述する箇所、フォームのエラーチェックを行う箇所等、 各プロジェクトで規約を設けるか、或いは Struts をベースとして、縛りをきつくしたフレームワークの構築が必要になる。

・データベースにアクセスする仕組みが無い
Struts にはデータベースを操作する為の仕組みが無い為、別途用意する必要がある。 Logstorage では独自にクラスを作成したが、Jakarta Project の OJB や Torque 等の使用も検討に値する。
・struts-config.xml
struts-config.xml にはシステム全ての画面遷移情報が記述される為、非常に大きなファイルとなり編集が困難となる。 これは Struts 1.0 では回避できない問題なので、アクション名の命名規則を決め、名称の重複が発生しないようにする必要がある。 Struts 1.1 では「Sub Application」が導入され、各サブシステム、機能等によって struts-config.xml を分割できるようになる。

Strutsの仕組み

Struts は MVC (Model-View-Controller)モデルを採用したフレームワークであり、以下のようになっている。

Struts MVC Model
MVC


ActionServlet はクライアントからの要求を受け取ると、リクエストデータをアクションフォームビーンに格納し、アクションを呼び出す。 アクションは、アクションフォームビーンに格納されたデータを元にビジネスロジックを実行し、JSP を呼び出す。
アプリケーション毎に開発が必要となるのは、アクション、アクションフォームビーン、JSP と、ActionServlet が呼び出すアクション、 アクションフォームビーン、JSP を定義する struts-config.xml である。

作成する順番は、以下のようになると考えられる。
・struts-config.xmlの定義
・JSP の作成
・アクションフォームビーンの実装
・アクションクラスの実装

クラスの関連
Action & ActionForm

 



開発の実際

Webアプリケーション開発では、初期段階でプロトタイプ(HTML)を作成するのが良い。システムのイメージが掴みやすくなり、ユーザとの認識のズレを減らす事ができる。
また作成したプロトタイプはJSPへの変換元ソースとして使用できる為、実開発工程での工数削減にも繋がる。 尚、HTML から JSP への変換にはツールを使用することができる。Struts関連ツール を参照していただきたい。

では、以下のログイン画面プロトタイプを例に、開発手順を見ていこう。

register.html
<html>
<head>
<title>ユーザ登録画面</title>
</head>
<body>
<form>
ユーザID : <input type="text" name="userId"><br>
パスワード: <input type="password" name="password"><br>
<input type="submit" value="登録">
</form>
</body>
</html>

complete.html
<html>
<head>
<title>登録完了画面</title>
</head>
<body>
<h2>登録完了</h2>
ユーザID: infoscience<br>
パスワード: password<br>
</body>
</html>


1) struts-config.xml の編集

struts-config.xml を編集する。 編集する内容は、
・どのアクションフォームビーンにリクエストデータを格納するのか
・どのアクションを呼び出すのか
・アクション実行後、どの JSP を呼び出すのか
という3点である。以下に定義例を示す。

struts-config.xml
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts-config PUBLIC
          "-//Apache Software Foundation//DTD Struts Configuration 1.0//EN"
          "http://jakarta.apache.org/struts/dtds/struts-config_1_0.dtd">

<struts-config>
	<form-beans type="org.apache.struts.action.ActionFormBean">
		<form-bean name="registerForm"
		           type="jp.co.infoscience.sample.RegisterForm"/>
	</form-beans>
	<action-mappings type="org.apache.struts.action.ActionMapping">
		<action path="/register"
		        name="registerForm"
		        scope="session"
		        type="jp.co.infoscience.sample.RegisterAction"
		        input="/register.jsp">
			<forward name="success"
			         path="/complete.jsp"
			         redirect="false"/>
		</action>
	</action-mappings>
</struts-config>


赤字の部分が、アクションフォームビーンの定義になる。
アクションフォームビーン名、クラスを指定する。

青字の部分がアクションクラスの定義になる。
パス、アクションフォームビーン名、スコープ、クラス、遷移元JSP、遷移先JSPを指定する。

上記例では、/register という名前でリクエストがあった場合、
・jp.co.infoscience.sample.RegisterForm にリクエストデータを格納 (RegisterForm は session スコープ)
・jp.co.infoscience.sample.RegisterAction(execute method) を呼び出す
・jp.co.infoscience.sample.RegisterAction(execute method) 内で success が指定された場合、complete.jsp を表示
・jp.co.infoscience.sample.RegisterAction(execute method) 内で、自画面再表示が指定された場合、register.jsp を表示 (入力エラーの場合等)
という処理を行う事になる。

2) JSP の作成

プロトタイプを元に、以下のように JSP を作成する。

register.jsp
<%@ page language="java" contentType="text/html; charset=EUC-JP" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>

<html:html>
<head>
<title>ユーザ登録画面</title>
</head>
<body>
<html:errors/>
<html:form action="/register" method="post">
ユーザID : <html:text property="userId"/><br>
パスワード: <html:password property="password"/><br>
<html:submit value="登録"/>
</html:form>
</body>
</html:html>

complete.jsp
<%@ page language="java" contentType="text/html; charset=EUC-JP" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<html:html>
<head>
<title>登録完了画面</title>
</head>
<body>
<h2>登録完了</h2>
ユーザID: <bean:write name="user" property="name"/><br>
パスワード: <bean:write name="user" property="password"/><br>
</body>
</html:html>


赤字の部分が Struts タグライブラリの使用の宣言、青字の部分がStruts タグライブラリを使用している箇所である。
Struts で用意されているタグライブラリの概要は、タグライブラリ を参照して頂きたい。

 



 

3) アクションフォームビーンの作成

以下のようにアクションフォームビーンを作成する。

RegisterForm.java
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionMapping;

public class RegisterForm extends ActionForm {
    private String userId = null;
    private String password = null;

    public String getUserId() {
        return this.userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getPassword() {
        return this.password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
    
    public void reset() {
        this.userId = null;
        this.password = null;
    }
    
    public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
        ActionErrors errors = null;

        if (getUserId().length() < 1) {
            errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("ユーザIDを入力してください。"));
        }
        return errors;
    }
}

アクションフォームビーンは、org.apache.struts.action.ActionForm クラスを継承して作成する。
アクションフォームビーンで宣言される内容は、基本的に JSP ファイルのプロパティと一致させる必要がある。
入力値のチェックを行う validate メソッド、初期化を行う reset メソッドも用意する。

4) アクションクラスの作成

以下のようにアクションクラスを作成する。

RegisterAction.java
package jp.co.infoscience.sample;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;

public class RegisterAction extends Action {

    public ActionForward execute(
        ActionMapping mapping,
        ActionForm form,
        HttpServletRequest request,
        HttpServletResponse response) {

        HttpSession session = request.getSession();
        ActionErrors errors = new ActionErrors();

        RegisterForm registerForm = (RegisterForm) form;

        // データベースへの登録処理
        // ....

        session.setAttribute("user", registerForm);

        return mapping.findForward("success");
    }
}

アクションクラスは、org.apache.struts.action.Action クラスを継承して作成する。
次画面に渡したい値は基本的に request か session に追加する。
上記では、赤字の部分で、session に "user" という名前で RegisterForm のインスタンスを追加し、 青字の部分で、"success" のマッピング先にフォワードしている。
"success" のマッピング先は struts-config.xmlの編集 で complete.jsp にフォワードするよう定義されているので、complete.jsp が表示される。


以上が、Struts における大まかな開発の流れである。
元となるHTMLプロトタイプがあれば、アクションフォームビーンは機械的に作成でき、JSP についても基本的に大きな修正は必要ないので、 プログラマはロジックに注力する事ができる。 Struts 1.1 ではアクションフォームビーンを内部的に生成してくれる DynaBean という仕組みがあり、さらに容易となる。

 



タグライブラリ

Struts には、以下のタグライブラリが用意されている。

bean タグライブラリ

JavaBean の操作を行うタグライブラリ。
タグ名 概要
cookie 指定したリクエストクッキーの値に基づいて変数を定義します。
define 指定した bean プロパティの値に基づいて変数を定義します。
header 指定したリクエストヘッダの値に基づいて変数を定義します。
include 動的なアプリケーションリクエストから応答をロードして bean として利用可能にします。
message 応答となる国際化されたメッセージ文字列を表現します。
page 指定したアイテムをbeanとしてページコンテキストから取り出します。
parameter 指定したリクエストパラメータの値に基づいて変数を定義します。
resource Web アプリケーションのリソースをロードして bean として利用可能にします。
size Collection または Map の要素数を含む bean を定義します。
struts 指定したStruts内部コンフィグレーション オブジェクトを bean として取り出します。
write 指定した bean プロパティの値を現在の JspWriter として表現します。

html タグライブラリ

HTMLタグを生成するタグライブラリ。
タグ名 概要
base HTMLの <base> 要素を表現します。
button ボタンフィールドを表現します。
cancel キャンセルボタンを表現します。
checkbox チェックボックスフィールドを表現します。
errors 蓄積されたエラーメッセージを条件付で表示します。
file ファイル選択フィールドを表現します。
form 入力 フォームを定義します。
hidden 隠蔽フィールドを表現します。
html HTMLの <html> 要素を表現します。
image "image"形式の入力タグを画像ボタンを表現します。
img HTMLのimg タグを表現します。
link HTML の アンカ または ハイパーリンクを表現します。
multibox チェックボックスフィールドを表現します。
option セレクトオプションを表現します。
options セレクトオプションのコレクションを表現します。
password パスワードフィールドを表現します。
radio ラジオボタンを表現します。
reset リセットボタンを表現します。
rewrite URIを表現します。
select セレクト要素を表現します。
submit サブミットボタンを表現します。
text テキストフィールドを表現します。
textarea Textarea要素を表現します。

logic タグライブラリ

JSP内で条件分岐、繰り返し等の制御を行うタグライブラリ。
タグ名 概要
equal 要求された変数が指定した値と等しい場合、このタグ内の内容を評価します。
forward ActionForward エントリによって指定したページへのフォワード制御。
greaterEqual 要求された変数が指定した値より大きいか等しい場合、このタグ内の内容を評価します。
greaterThan 要求された変数が指定した値より大きい場合、このタグ内の内容を評価します。
iterate 指定したコレクションで、このタグ内の内容を繰り返し評価します。
lessEqual 要求された変数が指定した値より小さいか等しい場合、このタグ内の内容を評価します。
lessThan 要求された変数が指定した値より小さい場合、このタグ内の内容を評価します。
match 指定した値が要求した変数の部分文字列に一致する場合、このタグ内の内容を評価します。
notEqual 要求された変数が指定した値と等しくない場合、このタグ内の内容を評価します。
notMatch 指定した値が要求した変数の部分文字列に一致しない場合、このタグ内の内容を評価します。
notPresent 指定した値がこのリクエストの中にない場合、このタグ内の内容を生成します。
present 指定した値がこのリクエストの中にある場合、このタグ内の内容を生成します。
redirect HTTP Redirectを表現します。

template タグライブラリ

テンプレート機能を提供するタグライブラリ。
タグ名 概要
insert テンプレートを挿入します(実際に取り込む)。 テンプレートはパラメータ化された内容を含んでいるJSPページです。 内容は、insertタグの子供であるputタグから受け継ぎます。
put 内容をリクエストスコープに配置します。
get putタグによりそこから配置された内容をリクエストスコープから取り出します。

 



Struts 関連ツール

Struts Console

無償
機能/特徴:
・struts-config.xml GUI編集
・HTML -> JSP(Struts Custom Tag)コンバート
・殆どのIDEでプラグインとして利用可能
URL : http://www.jamesholmes.com/struts/console/

Easy Struts

無償
機能/特徴:
・struts-config.xml GUI編集
・HTML -> JSP(Struts Custom Tag)コンバート
・ActionForm 自動生成
・Eclipse, JBuilder のプラグインとして利用可能
URL : http://easystruts.sourceforge.net/

Camino

有償 (1ユーザ $250 〜)
機能/特徴:
・struts-config.xml GUI編集 (Visual Modeling, Sub Application対応)
・HTML -> JSP(Struts Custom Tag)コンバート
・ActionForm 自動生成
URL : http://www.scioworks.com/

情報源

The Apache Struts Web Application Framework

Struts 提供元。
URL : http://jakarta.apache.org/struts/index.html

The Ja-Jakarta Project Struts翻訳

Ja-Jakarta Project による Struts ドキュメントの翻訳。
URL : http://www.ingrid.org/jajakarta/struts/

Struts ファンページ in Japan

Struts最新ニュース、FAQ 等。
URL : http://homepage2.nifty.com/ymagic/struts/

Struts メーリングリスト

約2000人が参加する、日本語による Struts 情報メーリングリスト。
URL : [参加フォーム] http://ml.excite.co.jp/cats/computer_internet/software/struts-user-freeml.html
URL : [全文検索]
http://www.freeml.com/ctrl/html/MessageListForm/struts-user