さて、実際にStrutsを使ってWebアプリケーションを作成してみましょう。ここでは、数当てゲームを作成してみます。数当てゲームは以下の処理を行います。
(1)スタート画面:ユーザは最初、ユーザ名と数字を入力
(2)入力値判定:サーバ中で発生させた乱数とユーザが入力した数字を比較
・数字が不正解の場合:その数字がサーバ内の数字より大きいか小さいか画面に表示し、数字の入力を求める。
・数字が正解の場合:正解メッセージを表示し、ゲームを終了
(3)例外処理Exception発生時:例外処理を行い、エラー画面を表示
上記を満たして、条件分岐と例外処理など、一通りStrutsの機能を利用するアプリケーションを作成することができます。Struts Studioを利用すると、図3のようにGUIで画面遷移を定義することができます。
筆者は、Strutsを利用するのが非常におっくうでした。まず、インストール方法がよく分からなかったり、やっとインストールできてもstruts-config.xmlの書式を理解するのが面倒だったり、苦労してstruts-config.xmlを作成しても、JSPやロジックを実行するアクションクラスに埋め込んだ値と整合性が取れずエラーが頻出したりと、とにかく使いにくいフレームワークでした。しかし、Strutsを利用したアプリケーションを開発するために生まれたStruts StudioによってStrutsの利便性は向上しました。ここで利用するStruts Studioには、次のような特徴があります。
Struts Studioには、Community Edition/Standard Edition/Professional Editionが用意されており、Community Editionは無料(注)で利用可能となっています。
注:ExadelのWebサイトではfreeとしか書いていなかったので、コマーシャルプロダクトの開発に利用可能かどうか問い合わせたところ、利用できるという回答をいただきました。
(1)インストール
ExadelのStruts Studioの配布サイト(http://www.exadel.com/products_strutsstudio.htm)からStruts Studio Community Editionをダウンロードしインストールします。ダウンロードにはユーザー登録が必要なので、注意してください。Struts StudioにはWindows版とLinux版が用意されていますが、ここでは、Windows版を用いて解説します。
Struts Studioの起動は、Windows版の場合は、スタートメニューから「Struts Studio 4.7 with Console」を選択することで起動できます。Struts Studioの画面を簡単に解説すると、図4のようになります。
それぞれの画面要素を説明しましょう。
(2)プロジェクト作成
Struts Studioは一般的なJavaのIDEと同じように、プロジェクトでアプリケーションを管理します。プロジェクトを作成するには、メニューの[File]→[Create New Project]を選択し、Nameフィールドにプロジェクト名を入力します。[Next]ボタンを押し、次の画面で[Finish]をクリックします。ここでは、プロジェクト名に「guess」を入力します。
Struts Studioで画面遷移を作成してみましょう。左のナビゲーションパネルから「WEB-INF/struts-config.xml」をダブルクリックで選択します。すると、ダイアグラムビューが表示されます。ダイアグラムビュー上で右クリックし、 メニューからAddを選択すると、次のメニューが表示されます。
メニュー | 解説 | |
---|---|---|
Action | アクションの作成 | |
Global Foward | グローバルフォワードの作成 | |
Global Exception | グローバル領外への作成 | |
Page | JSPページの作成 | |
Struts Studioでは、この4つを作成しながら、画面遷移を作成することになります。では実際に数当てゲームの画面遷移を作成してみましょう。
(1)グローバルフォワードの作成
まずグローバルフォワードを作成しましょう。グローバルフォワードは、Webアプリケーションの開始点です。ユーザーはまず、グローバルフォワードからリンクされた画面に最初にアクセスします。
ここでは、Webアプリケーションが開始すると数字入力画面「/pages/start.jsp」を表示するグローバルフォワードを作成します。strutsコンフィグエディタ上で右クリックし、「Grobal Foward」を選択し、表示されたダイアログ(図6)で次のように入力してください。
項目 | 入力値 | 解説 | |
---|---|---|---|
name* | start | 名前 | |
path* | /pages/start.jsp | 実行するパス | |
redirect | リダイレクトの設定 | ||
contextRelative | モジュールの設定 | ||
ダイアログ右下の[Help]を押すとダイアログの解説を英語で見ることができます。[OK]を押すと、ダイアグラムビューが図7のように変化し、struts-config.xmlへの設定追加と「/pages/start.jsp」の生成を自動的に行います。
注:以降の説明ではプロパティ設定のダイアログの画面は省略します。
(2)アクション
アクションは、ロジックの実行単位です。アクションの設定によりコントローラであるActionServletの動作を決めることになります。図8を用いて簡単に説明します。
上記のフォームBean/アクションクラスの設定をここで行います。ダイアログビュー上で、右クリック→[Add]→[Action]を選択し、現れたダイアログで、次のように入力します。
フィールド | 入力値 | 解説 | |
---|---|---|---|
name | guessform | フォーム名 | |
path* | /guess | アクションが関連付けられるパス。アクションは、*.doで表記されるURLに対応付けられる(ここの場合/guess.do) | |
scope | session | アクションフォームのスコープです。session,requestを選択できます。 | |
type | GuessAction | アクションクラスのクラス名 | |
validate | false | Struts Valdatorにより、フォームの入力値の妥当性検証を行うかどうか指定。 | |
アクションが作成されると、ダイアグラムビューに次のように表示されます。
この情報は、左のナビゲーションパネルの「struts-config.xml/action-mappings」にも表示されます。ここで、ダイアログビューの「/pages/start.jsp」にカーソルを合わせてクリックし、いま作成したアクションguessに線をドラッグして持っていくと図10のようになり、start.jspのフォームを入力して、guessアクションを実行させることができます。
(3)フォワードの作成
アクションを実行した結果、どの画面を表示するか、あるいは次にどのロジックを実行するかをフォワードで定義します。
次のように遷移先を設定します。
ケース | 遷移先 | |
---|---|---|
入力した数字が正解の場合 | /pages/match.jsp | |
入力した数字が不正解の場合 | /pages/unmatch.jsp | |
先ほど作成したguessformと表示されたアクションのアイコンを右クリックし、[Create Forward]を選択します。現れた画面で必要な情報を入力します。例えば、matchには次のように入力します。
項目 | 入力値 | 解説 | |
---|---|---|---|
name: | match | フォワード名 | |
path: | /pages/match.jsp | フォワード先の情報 | |
redirect: | リダイレクトの設定 | ||
contextRelative: | モジュールの設定 | ||
同じく「Create Forward」を選択しunmatchに、以下のように入力します。
項目 | 入力値 | |
---|---|---|
name: | unmatch | |
path: | /pages/unmatch.jsp | |
redirect: | ||
contextRelative: | ||
2つのフォワードを作成すると、フォワード先のJSPが自動的に生成されます。最後に、unmatch.jspからguessアクションへリンクを張れば、数当てアプリケーションの画面遷移は完成します(図11)。
さて、画面遷移が完了したら、アクションと画面の間で値をやりとりするフォームBeanとロジックを実行するアクションクラスを作成しましょう。
(1)フォームBeanの作成
アクションクラスとJSPの間でパラメータをやりとりするためのフォームBeanを作成します。Struts 1.0では、フォームBeanをユーザーがコーディングする必要がありましたが、Srtuts 1.1から導入されたDynaFormを利用すると、アクションフォームBeanを作成する必要がなくなり、プロパティをセットするだけでよくなります。ここでは、後でユーザーの入力値の妥当性検証を行うことを考慮して、DynaFormBeanに妥当性検証機能を追加したDynaValidatorFormを利用します。
ナビゲーションパネルの「/WEB-INF/struts-config.xml/form-beans」を選択し、右クリックで「Create FormBean」を選択します(図12)(注)。
注:以降、/XXX/YYYと記述した場合、ナビゲーションパネルのツリーの位置を表すこととします。
以降、表示されたダイアログで、表6のように入力します。
項目 | 入力値 | |
---|---|---|
name* | guessform | |
type* | org.apache.struts.validator.DynaValidatorForm | |
すると、ナビゲーションパネルのform-beansにguessformが生成されます。ここで注意点があります。name*は、ダイアログビュー上のアクションの名前と同じにして下さい。
このフォームBeanをDynaFormとして利用するための設定を行います。ナビゲーションパネルのguessformを右クリック→「Properties」→「Advanced」タブを選択し、dynamicプロパティをtrueにします。
フォームBeanで利用するプロパティを追加します。ナビゲーションパネルのguessformを右クリックし、「Create Form Property」を選択、表示されたダイアログで次のように入力します。
フィールド | 入力値 | 名前 | |
---|---|---|---|
name | num | プロパティ名 | |
type | java.lang.String | プロパティの型 | |
initial | 初期値 | ||
size | サイズ | ||
上記のnumを利用して、JSPのフォームからの入力値の取得と出力値の設定を行います。さらに、ユーザーの名前を取得するnameプロパティ(name:name、type:java.lang.String)と、ユーザーが入力した数字が大きいか小さいかロジックで判定した結果を入れるisGreaterプロパティ(name:isGreater、type:java.lang.String)について、表7のように定義します。
定義が完了すると、次のようになります。
画面を見ると、一目でguessformに「num/isGreater/name」の3つのプロパティが定義されていることが分かります。
次に、ナビゲーションパネルから「plug-ins」を選択し、右クリックで「Create SpecialPlug-in」→「Validators」を選択します。これは、DynaValidatorFormもしくは、ValidatorFormの固有の設定です。
(2)アクションクラスの作成
アクションクラスでは、以下のことを行います。
アクションクラスを生成するには、アクションを右クリックし、現れたダイアログに必要情報を入力します。
フィールド | 入力値 | 名前 | |
---|---|---|---|
Action class | GuessAction | アクションクラス名 | |
Base class: | org.apache.struts.action.Action | アクションクラスの基底クラス | |
Imports | (値なし) | このアクションクラスでimportするクラス | |
Generate JavaBeaan porperties | v | JavaBeansのプロパティを生成 | |
Generate contants for local forwards | v | グローバルフォワードのための定数生成 | |
Generate constants for local forwards | v | ローカルフォワードのための定数生成 | |
Output path* | (値なし) | ソースを生成するディレクトリ | |
設定が終わったらGenerateボタンを押します。すると、アクションクラスが生成されます。あとは、executeメソッドにロジックを実装します。エディタを用いた開発では、フォワード名とstruts-config.xmlの設定値を間違えてエラーが発生し、この誤りの原因を突き止めるのに苦労するといったことがありますが、Struts Studioで作成したアクションクラスには、struts-config.xmlの情報を基に、次のようにフォワード名が定義されるので、その心配はありません。
public class GuessAction extends org.apache.struts.action.Action { |
アクションの実行内容は、次のようにexecuteメソッドに実装します。
GuessAction.java |
… |
executeメソッドを実装する注意点としては以下の点が上げられます。
ここでは、入力したソースコードは、左上にあるbuildアイコンから「build」を選択するとAntを利用してコンパイルできます。
(3)コントローラの設定
HTTPヘッダのパラメータの設定、ブラウザから入力したリクエストを処理するリクエストプロセッサの設定などを行います。
まず、日本語がブラウザ上で正しく表示されるようにHTTPヘッダのcontentTypeの設定を行います。ここでは、ナビゲーションパネルの「WEB -INF/struts-config.xml/controller」を右クリックし「CreateProperty」を選択、次の値を入力します。
フィールド | 入力値 | |
---|---|---|
property* | contentType | |
value* | text/html;charset=Windows-31J | |
initial | ||
size | ||
次に、ブラウザからの日本語入力を正しく処理できるようにリクエストプロセッサを作成、登録します。リクエストプロセッサは、その名のとおり、HTTPのリクエストを処理するクラスです。アクションの実行は、このリクエストプロセッサから呼び出されます。リクエストは、リクエストプロセッサのprocessメソッドを実行することにより行われますが、デフォルトのリクエストプロセッサorg.apache.struts.action.RequestProcessorを継承したクラスの直前にリクエストの文字コードを指定することで、フォームの入力値の文字化けを回避することができます。
ナビゲーションパネルの「/src」を右クリックし、「Create」→「File」→「Java」を実行してCharsetProcessorクラスを作成します。
CharsetProsessor.java |
import javax.servlet.http.*; |
リクエストプロセッサを登録するには、ナビゲーションビューから「/WEB-INF/struts-config.xml/controller」を選択すると、controllerタグの属性が表示されるので、processorClassにクラス名CharsetProcessorを設定します。設定が完了すると、図15のような画面になっているはずです。
なお、リクエストの文字コードの設定については、今後、リクエストプロセッサを登録しなくとも文字コードを指定できるように改良したいと考えています。
(1)JSPの作成
JSPの画面を作成します。ダイアグラムビューで、JSPをクリックすると、JSPエディタが起動します。
このエディタで各JSPに対して、リストxx、リストxx、リストzzのように入力します(bodyタグなど、解説の不要なタグは省略しています)。
StrutsのJSPでは、通常のHTMLタグの代わりにhtml:xxxタグやlogic:xxx、bean:xxxタグを利用してJSPを作成します。これらStruts固有のタグを利用することにより、URLを適切なパスに展開したり(html:form)、簡単な条件分岐や値チェックを行ったり(logic:xxx)、Webブラウザのフォームで入力した値をフォームBeanに対応付けたり(html:text)、フォームBeanのプロパティの値を表示したり(bean:write)することができます。
リスト:start.jsp |
<%@page pageEncoding="Windows-31J"%> |
リスト:unmatch.jsp |
<%@page pageEncoding="Windows-31J"%>
|
リスト:match.jsp |
<@page pageEncoding="Windows-31J"%> |
(2)アプリケーションリソースの設定
アプリケーションリソースはエラーメッセージなどのメッセージを記述するプロパティファイルです。アプリケーションリソースは後で利用しますが、これを設定しておかないとStrutsが動作しません。「WEB-INF/struts-config.xml/resources」を選択し右クリックで「Define Message Resources」を選択します。ダイアログで、以下のように入力し、[OK]を押します。
parameter*: ApplicationResources
|
さて、準備ができたら、アプリケーションを実行してみましょう。左上のTomcatランチャから左から2番目の三角のアイコンをクリックすると、Tomcatが起動します。Tomcatの起動の様子は下のコンソールに表示されます。Tomcatが起動したら、グローバルフォワード(ここでは、「start」のアイコン)を右クリックして「run」を選択するだけで、ブラウザが起動し、Webアプリケーションを実行できます。
Actionクラスなどのコードを変更した場合は、Tomcatランチャの一番右の手のアイコンをクリックするとWebアプリケーションがリロードされ、Tomcatを再起動することなく更新したアプリケーションでテストできます。
さて、先ほど作成した数当てゲームは、例外処理が入っていませんでした。これに例外処理を入れてみましょう。Strutsには、次の2つの例外処理の機構があります。Strutsは、エラー処理として次の2つをサポートしています。
では、それぞれについて具体的に見ていきましょう。
(1)フォーム入力値のエラー
Struts Validatorを利用すると、フォームの入力値の妥当性検証を簡単に行うことができます。また、検証方法もクライアントサイドの検証とサーバサイドの検証を同時に行うことができます。妥当性検証を行うには、ValidatorFormを継承したフォームBeanを用いるか、DynaValidatorFormを利用する必要があります。すでにDynaValidatorFormを利用しているので、ここでは、validationの設定方法を説明します。
妥当性検証ファイルvalidation.xmlを設定します。ナビゲーションパネルから/WEB-INF/validation.xmlをクリック、エディタを起動し次の太字の部分をformsetタグの後ろに追加します。
/WEB-INF/validation.xml |
<formset> |
ここでは、guessformのnumプロパティに対し、値の入力が必須(required)で、short型の数値(short)という条件で検証の条件を設定しています。
次に、エラーメッセージなどのメッセージを記述するアプリケーションリソースを準備します。ここでは、ナビゲーションパネルの「src」ディレクトリを選択し、右クリック→「Create」→「File」→「Properties」と選択し、nameフィールドにApplicationResourcesを入力し、ApplicationResource.propertiesを作成します。そして、プロパティのnameとvalueをそれぞれ次のように設定します。
name | value | |
---|---|---|
errors.required | {0}が空です。値を入力して下さい。 | |
errors.short | 数字を入力して下さい。 | |
guessform.num.name | 数字 | |
ここで、先ほどのvalidation.xmlの次の行に注目して下さい。
depends="required,short"> |
上記の値は、requiredに対するエラーメッセージはアプリケーションリソースのerrors.requiredに、shortに対するエラーメッセージはerrors.shortに記述します。また、errors.requiredに{0}という記述がありますが、これは、validation.xmlのarg0要素で指定されたアプリケーションリソース「guessform.num.name」の値(「数字」)に対応付いています。
プロパティは、unicodeエスケープで保存する必要がありますが、Struts Studioのプロパティエディタはunicodeエスケープに対応していません。そこで、コマンドプロンプトを起動し、C:\StrutsStudio\tomcat\webapps\hello\WEB-INFに移動し、次のように実行します。
>
native2ascii src\ApplicationResources.properties classes\ApplicationResources.properties |
これで、プロパティファイルがunicodeエスケープに変換されてclassesディレクトリに保存されます。
unmatch.jsp(赤字の部分を追加) |
<%@page pageEncoding="Windows-31J"%> |
(2)アクションの設定
ダイアグラムビューで「/guess」アクションを右クリックしてプロパティを表示し、次のようにプロパティを設定します。
Name | Value | 解説 | |
---|---|---|---|
validate | true | Struts Valdatorにより、フォームの入力値の妥当性検証を行うかどうか指定。 | |
input | /pages/unmatch.jsp | エラーが発生した時に遷移する画面 | |
これで、guessアクションに対するサーバサイドの妥当性検証unmatch.jspに対するクライアントサイドの妥当性検証が有効になります。最初の画面で数字を入力する場所に数字以外の値を入力すると次のようにエラーが表示されます。
また、unmatch.jspで数字以外の文字を入力すると、JavaScriptにより、次のようにエラーが表示されます。
(3)システム例外
アクションクラスの中で、ロジックを実行する際に発生したExceptionによりエラー用ページに遷移させることができます。DBエラーなどのシステム障害が発生した場合には、この仕組みを利用するとよいでしょう。例外処理には、グローバル例外とローカル例外の2つの例外処理機構があります。グローバル例外は、すべてのアクションで発生した例外を処理でき、ローカル例外は各アクションで発生した例外を処理するという違いがあります。Struts Studioを用いると、グローバル例外の作成を簡単に行うことができます。ダイアグラムビュー上で右クリック、Global Exceptionを選択し、表示されたダイアログで次のように入力します。
フィールド | 入力値 | 解説 | |
---|---|---|---|
key* | errors.exception | エラーメッセージ | |
type* | java.lang.Exception | Exceptionの型 | |
path | /pages/error.jsp | 遷移先の画面 | |
type | GuessAction | アクションクラスのクラス名 | |
scope | (値なし) | スコープ | |
すると次のようになります。
この遷移図がExceptionが発生した場合、「/pages/error.jsp」を表示することは一目でわかりますね。あとは「/pages/error.jsp」をクリックして次のように入力します。
error.jsp |
<%@page pageEncoding="Windows-31J"%> |
そして、エラーメッセージをApplicationResources.propertiesに追加します。
name | value | |
---|---|---|
errors.exception | システム障害が発生しました。恐れ入りますが、現在サービスをご利用になることはできません。 | |
ApplicationResources.propertiesを編集したら、先ほどと同じようにnative2asciiを利用して変換して下さい。
すでに日本語を利用する方法は本稿中で述べていますが、ここでまとめてみましょう。
(1)JSPファイルのpageディレクティブでpageEncodingを設定する
<%@page pageEncoding="Windows-31J"%>
|
もし、日本語が正しく扱えない場合は、これらの点に注意してみましょう。また、Unix環境ではWindows-31Jの代わりにEUC-JPを利用するとよいでしょう。
Strutsの基本とStruts Studioを利用したWebアプリケーションの開発について紹介してきました。Struts Studioを利用すれば、面倒だったstruts-config.xmlの編集の必要がなくなり、初心者でも直感的にStrutsを利用できるようになります。Struts Studioは現在は英語版しかリリースされていませんが、今後の日本語版のリリースに期待したいところです。
最後になりましたが、残念ながら、本連載、「現場に活かすJakarta Project」は今回で最終回となります。総論から始まり、Ant、Commons、Taglib、Tomcat WebDAV、そして、Strutsと紹介してきました。連載当初JakartaのプロジェクトであったAnt、Avaon、Jamesは個別プロジェクトへ移動し、Torque/OJBも新設されたApache DBプロジェクトへ移動しました。Turbineのコンポーネントの1つだったMavenも独立したプロジェクトとなり、Antに変わるビルドツールとして注目を浴びています。この1年はまさにJakartaプロジェクトにとって激動の年といえるでしょう。また、サーバサイドJavaのオープンソースといえばJakartaでしたが、アプリケーションサーバのJBossやO/RマッピングツールのHibernate、メタデータによる新しいスタイルのプログラミングを提供するXDoclet、そして、爆発的な勢いで普及しているIDEのEclipseなど、Jakarta以外にも使えるオープンソースは多数現れています。一昔前はJavaのオープンソースといえば、Jakartaでしたが、そのような時代はすでに終わっているといって過言ではないでしょう。しかし、Jakarta以外のオープンソースでも、よく見ると、JBossではTomcatを、HibernateはCommonsのLoggingやDBCPを、XDocletはAntを利用しています。いま、Jakarta以上に注目されているEclipseもTomcat、Ant、Luceneがインテグレートされています。Jakarta以外のほかのJavaのオープンソースも注目され始めたとはいえ、Javaのオープンソースにとって、Jakartaの重要性は今後ますます大きくなっていくといえるでしょう。
今回の連載は、どちらかといえば入門者向けの記事でしたが、本連載を機にJakartaのプロダクトのユーザーが1人でも増えればと思います。また、機会があればより実践的な話をご紹介したいと思います。
最後に、連載にご協力いただいたJa-Jakartaプロジェクトの小山、横田両氏とJakartaのプロダクトの日本への普及を促進すべくドキュメントの翻訳や日本からのフィードバックに精進されているJa-Jakartaプロジェクトメンバーおよび本連載の読者の皆さまに感謝します。読者の皆さまには、機会があれば、ぜひJa-Jakartaの活動に参加していただければ幸いです。中にはオープンソースプロジェクトへの参加は難しそうと思われる方がいらっしゃるかもしれませんが、Ja-Jakartaプロジェクトへ参加することは決して難しくありません。今後、読者とライターという関係ではなく、一緒に活動する仲間としてお会いできれば幸いです。
岡本隆史(おかもと たかし)
岡山大学工学研究科修了後、(株)NTTデータに入社。文字認識ソフトウェアの研究開発を経て、Webサービス関連の研究開発に携わる。個人では、Debian GNU/Linuxの優れたメンテナンス性とほかのディストリビューションを圧倒するパッケージ数に引かれDebianを使い始めたのをきっかけに、Debianプロジェクトの開発者となる。DebianプロジェクトのStefan Gybas、Ola Lundqvistらとともに、Javaサポートの強化を行う。Jakartaに関しては、Tomcat/JMeter/ORO/Luceneなどの国際化/日本語へのローカライズ、AntのKaffe VM対応などを行っている。『Jakartaプロジェクト徹底攻略』(技術評論社)、『WEB+DB PRESS』(技術評論社)、『Java World』(IDGジャパン)、『JAVA Developer』(ソフトバンクパブリッシング)などで執筆活動を行っている。
Ja-Jakarta Projectについて
Ja-Jakartaプロジェクトでは、Jakartaプロジェクトのドキュメントの和訳やプロダクトの国際化/日本語化などを行っている。現在、プロジェクトのメンバーを募集中。Ja-Jakartaプロジェクトの活動に参加しようという方は、「Ja-Jakartaプロジェクトへの参加方法」(http://www.jajakarta.org/site/getinvolved.html)を参照。
Copyright © ITmedia, Inc. All Rights Reserved.