Eclipse で Struts フレームワーク・プログラム開発
Struts とは,Web アプリケーション開発のフレームワークです. Apache Jakarta プロジェクトの成果物です.
このページでは,Eclipse の機能を使いながら,Struts フレームワークに準拠した Java サーブレット・プログラムを開発(設計と実装)する手順を説明する. さらに,Eclipse で, 出来たJava サーブレット・プログラムを,Tomcat 上で動作させます. 以上のことを,プロラムの見本と,操作手順の図解で説明する.
* Tomcat と Java サーブレット・プログラムの全般については,別の Web ページを見てください.
【この Web ページの目次】
【補足説明】
下記の 2つのサーバは別物です. 2つを同時に動かすことはできません(ポートを奪い合うことができないので).一方を動かすときは,もう一方を止めることになる.
- Eclipse 内部の tomcat サーバ:
Eclipse では,Eclipse 内部の Tomcat サーバが動き, Java サーブレットの動作テストなどに使う.
- 公開 tomcat サーバ:
Eclipse とは無関係の Tomcat サーバ(C:\tomcat55\bin\tomcat5w.exe で起動する Tomcat サーバのこと).当然, 公開 tomcat サーバが管理するディレクトリも Eclipse とは無関係.
* なお,「Eclipse 内部の tomcat サーバ」を使えるようするには, Eclipse で「新規サーバの定義」という操作を行う必要がある.これは,1回行うだけで十分です.
Struts について
次のものが出てきます. 練習の目的は,それぞれの役割と,互いの関係を理解することです.
- Web ブラウザにページとして表示される JSP プログラム
Web ブラウザに表示されるページのデザインと中身(フォーム,動的データなど)が定義される.
JSP プログラムは,Struts タグライブラリを使って,アクションフォーム・ビーンなどの属性値を取り出す.
- クライアントから入力されたフォームデータを格納するStruts アクションフォーム・ビーン・クラス
Struts アクションフォーム・ビーン・クラスは, 入力フォームとマッピングされ, 入力フォームに記入されたクライアントからのフォームデータの格納と検証を行う. さらに,フォームデータを検証し,エラーがあれば ActionErrors オブジェクトを生成する validate メソッドを持つ.
Struts アクションフォーム・ビーンの有効期限(スコープ)は, セッションの期間,つまり,個々の HTTP リクエストよりも長く設定でき, この場合, 個々の HTTP リクエストの期間を超えて共有される.
Struts アクションフォーム・ビーン・クラスには, 入力フォームの項目に対応する属性等が定義される. アクションフォーム・ビーン・クラスの属性名は,入力フォームに登場する属性名と一致させるのが普通である. さらに,属性のゲッター(属性ゲッターメソッドのこと,getXxx の形)とセッター(属性セッターメソッドのこと.setXxx の形)を持つ.ゲッターとセッターは,JSP プログラム,Struts アクションクラス,ビジネスロジックから使用される. さらに,Struts アクションフォーム・ビーンを初期化するためにreset メソッドを持つ.
Struts アクションフォーム・ビーン・クラスは, Web アプリケーションの,個々の入力フォームに対応して定義されるクラスである. 但し,入力フォームが複数のページにまたがる場合に,Struts アクションフォーム・ビーンがページ数よりも少ないことがありえる. Struts の org.apache.struts.action.ActionForm クラスのサブクラスとして定義される.
- システム内部状態が定義されたクラス
システムの内部状態は,Java ビーンあるいはJava ビーンの集合により表される. システム内部状態が定義されたクラスは,システムの内部状態に関する属性と,属性のセッターとゲッターを持つ.
有効期限(スコープ)は, セッションの期間,あるいは,システムの稼動期間である. つまり,個々の HTTP リクエストの期間を超えて共有される.
- Struts マッピング定義ファイルである struts-config.xml
画面遷移,アクションマッピング,アクションフォワードに関する定義が行われている設定ファイル.
- Struts アクションフォーム・ビーンの定義(識別子とクラス名)
- アクションの定義(アクション名,アクションクラス名,アクションフォームビーンを構成する属性名など)
HTTP リクエスト処理のためにアクションマッピング(HTTPリクエストと,特定のアクション・クラスの execute メソッドとのマッピング)と, アクションフォワードにおける,JSP プログラムのフォワード(Struts アクションマッピングオブジェクトと JSP プログラムとのマッピング)
- Struts 入力データ検証用設定ファイルである validation.xml
入力フォームに記入されるべきフォームデータの各項目について,データの種類や制約が記述されたファイル. データの種類や制約が満足されていることが自動的に検証され,エラーがあれば,所定の処理が行われる.
- Struts フレームワークが有するアクションサーブレット
Struts フレームワークが有するアクションサーブレットが,クライアントからの要求(HTTPリクエスト)を,適切な Struts アクション・クラスに委譲する. (所定の Struts アクション・クラスの execute メソッドが呼び出される). 同時に,フォームデータを,Struts アクションフォーム・ビーンに格納する. このとき,Struts アクションフォーム・ビーンの validate メソッドも使い,入力データの検証が行われる (これは,validation.xml による検証と別のもので,validation.xml では出来ない細かなエラー処理ができる).
- アクションに関する処理を行う,Struts アクション・クラス
Struts アクション・オブジェクトの役割は,大きく2つある. 1つは, HTTPリクエストとビジネスロジックを提供する Java ビーンとの間の仲介役である. もう1つは,アクションフォワードである.
Struts アクション・オブジェクトは,実際のHTTPリクエストの処理を行うために, ビジネスロジックを提供する Java ビーンを呼び出す. この呼び出しをディスパッチという. 「ディスパッチ」と書いているのは,Struts アクションは処理の振り分けのみで,実質的な処理は,ビジネスロジックで行われるという意味である. このディスパッチのために,Struts アクションフォーム・ビーンに格納されたデータ等が使用される. (アクションフォーム・ビーンを,セッターを使って設定するのは,Struts アクション・クラスの役目である)
Struts アクション・オブジェクトは, アクションフォワードを行う. これは,Struts アクションフォーム・ビーンに格納されたデータを使い,アクションフォワード・オブジェクトを生成する処理である. アクションフォワード・オブジェクトの値と,JSPプログラムとのマッピングは struts-config.xml に定義されている. これで,次のページへの遷移が行われる.
Struts アクション・クラスは,Struts の org.apache.struts.action.Action クラスのサブクラスとして定義される. 処理は,execute メソッドに実装される.
- ビジネスロジックを提供する Java ビーンのクラス
アプリケーションの各種機能は,ビジネスロジックを提供する Java ビーンのクラスに実装される.
アクションフォーム・ビーンを private メンバ属性として保持する(アクションフォーム・ビーンを,セッターを使って設定するのは,Struts アクション・クラスの役目である) ビジネスロジックを提供する Java ビーンにおける処理結果は,別の Java ビーン・オブジェクトに格納される.
準備事項
前準備
JDK (Java Development Kit) のインストール
Eclipse のインストール
その他
- Eclipse の GEF プラグインの インストールが終わっていること.
- Eclipse の 「Web, XML, and Java EE 及びエンタープライズ開発」に関するプラグインのインストールが終わっていること.
- 「Tomcat インストール」の Web ページの記述に従って,Tomcat のインストールが終わっていること.
* Ubuntu の場合には「Ubuntu で Tomcat バージョン 7 のインストールとテスト実行」を参考にしてください
- 「Eclipse 内部の tomcat サーバ」を使えるようにするために, 「Eclipse を使用しての Java サーブレット・プログラムの開発」の Web ページに記載 の「新規サーバの定義」を行っておくこと.
設定項目
前もって,Tomcat のバージョンを調べておいて下さい
- Tomcat のバージョン: Apache Tomcat v5.5
前もって,Tomcat インストールディレクトリを調べておいてください.このページでは,次のように書く.
- Tomcat インストールディレクトリ: C:\tomcat55
Eclipse での Struts プログラムの作成手順
以下,Eclipse を使う. プロジェクトの作成,クラスの定義と実行という一連の操作を,図解で説明する.
Eclipse の使用にあたって,事前に決めておく事項
Java サーブレット・プログラムを動かすために,Eclipse のプロジェクト等を作る. Web ページでは,プロジェクト名,Java パッケージ名は次のように記述します. (すでに同じ名前のプロジェクトがある,といったときは,プロジェクト名を変えてください).
- プロジェクト名: hoge
- Java パッケージ名: hoge.hoge.com
Struts を使う上で,作業場の重要な点(忘れやすい点)は,次の2つです.忘れずに行うこと.
- 動的 Web プロジェクトへの Struts サポートの追加 が必要である.
- Struts サポートの追加を行うときは,Web アプリケーションのルートとして,WebContent を指定すること.
ここでは,Struts プログラムの例を使って,作成手順を説明する.ファイル構成は次のようになっています.
├HLgame ├ : ├Javaリソース; src │└hoge.hoge.com │ ├StartAction.java │ ├HighAndLowAction.java │ ├HighAndLowForm.java │ ├HighAndLowData.java │ └BusinessLogic.java : ├WebContent ← Webアプリケーションのルート ├WEB-INF │ : │ ├struts-config.xml │ : │ ├validation.xml │ : │ ├index.jsp ├game.jsp └gameover.jsp
アクションとアクションフォーム・ビーンとJSPの関係は次のようになっています.
- アクションフォーム・ビーン
- アクションフォーム・ビーン名: highAndLowForm
- アクションフォーム・ビーン・クラス名: HighAndLowForm
- アクションとマッピング (highAndLowAction)
- パス(要求名): highAndLowAction
- アクションフォーム・ビーン名:highAndLowForm
- アクション・クラス名(要求時にこのクラスの execute が呼び出される): HighAndLowAction
- アクションフォーム・ビーンのスコープ: session
- input(遷移元JSP): /game.jsp
- フォワード(遷移先JSP): success, betmoneyfault ⇒ /game.jsp, gameover ⇒ /game.jsp
- アクションとマッピング (startAction)
- パス(要求名): startAction
- アクションフォーム・ビーン名:highAndLowForm
- アクション・クラス名(要求時にこのクラスの execute が呼び出される): StartAction
- アクションフォーム・ビーンのスコープ: session
- input(遷移元JSP): /index.jsp
- フォワード(遷移先JSP): success ⇒ /game.jsp
動的 Web プロジェクトの新規作成
下記の手順で,動的 Web プロジェクトを新規に作成する.
- (もし,プロジェクト・エクスプローラが開いていなければ)プロジェクト・エクスプローラを開く
「ウインドウ (Window)」→「ビューの表示 (Show View)」→「プロジェクト・エクスプローラ (Project Explorer)」 と操作する.
- プロジェクトの新規作成の開始
「ファイル」→「新規 (New)」→「プロジェクト (Project)」
または,プロジェクト・エクスプローラ内で,右クリック→「新規 (New)」→「プロジェクト (Project)」 - 「Web」の展開
新規プロジェクトのウインドウが開くので, 「Web」を展開する.
- 「動的 Webプロジェクト (Dynamic Web Project)」の選択
展開した「Web」の下にある 「動的 Webプロジェクト (Dynamic Web Project)」を選び, 「次へ」をクリック
- プロジェクト名の設定など
設定用のウインドウが開くので,下記の設定を行う. 設定が終わったら,「次へ」をクリック.
- 「プロジェクト名 (Project name)」(name)(1行目): HLgame と設定.
プロジェクト名は,好きな名前でよいが,スペースや全角文字は避けること. ここでは,プロジェクト名を,「HLgame」と付けることにする.
- 「プロジェクト・コンテンツ (Project contents)」(2行目)では,ファイルの保存場所を指定する.
「デフォルトの使用 (Use default)」にチェックを入れたままで良い.
- 「ターゲット・ランタイム (Target Server)」 (3行目):「Apache Tomcat ○○○」になっていることを確認.
バージョンが違う場合、「なし」になっている場合は、正しいバージョン(例えば「Apache Tomcat v5.5」)に変更しておく
* 変更のとき,「なし」だけしか無くて,「Apache Tomcat v5.5」などが候補として表示されない場合は, 「Eclipse を使用しての Java サーブレット・プログラムの開発」の Web ページに記載の「新規サーバの定義」を行うこと.
- 「プロジェクト名 (Project name)」(name)(1行目): HLgame と設定.
- 次の「プロジェクト・ファセット」は,デフォルトのままでよい
「次へ」をクリック.
* このウインドウが開かないことがある.気にしなくてよい.
- プロジェクト構成
- 次の「Web モジュール」は,デフォルトのままでよい
「web.xml デプロイメント記述子の生成」をチェックし、 「終了」をクリック.
- もし「関連付けられたパースペクティブを開きますか?」と聞いてきたら,「はい」をクリック
* このウインドウが開かないことがある.気にしなくてよい.
- 作成されたプロジェクトの確認
Eclipse 3.X を使用していて、StrutsIDE をインストールしている場合には、 次の手順で、「動的 Web プロジェクトへの Struts サポートの追加 」を行うことができる.
- 新規作成したプロジェクトである「HLgame」の「WebContent」を右クリック.
- 「新規」
- Strutsサポートの追加
「その他」→「Amateras」→「Struts」→「Strutsサポートの追加」と操作し, 「次へ」をクリック.
「Strutsサポートの追加」が出てこないときは, Eclipse StrutsIDE プラグイン の手順を行った後に, ここの手順を繰り返す.
- Struts サポートの設定の確認
Webアプリケーションのルートが,<プロジェクト名>/WebContent のようになっていることを確認.
なっていなければ,Web アプリケーションのルートを,<プロジェクト名>/WebContent のように設定
(<プロジェクト名>/WebContent の設定を忘れたら,プロジェクトの作成からやり直し)
- 「終了」
Struts用のJARファイルが設定されるとともに,各種設定ファイルのひな型が生成される.
XML ファイルとJSPファイルのエディタは,デフォルトでは WTP のエディタになっている.デフォルト以外のエディタで開きたいときは, XML ファイルとJSPファイルを右クリックして,エディタを選べる.
Apache Structs2 に関する設定
- ダウンロード
http://struts.apache.org/development/2.x/
- ダウンロードした ZIP ファイルを分かりやすいディレクトリに置き、展開(解凍)する
◆ Ubuntu での操作手順例
unzip struts-2.3.15.3-all.zip
- jar ファイルの確認
◆ Ubuntu での操作手順例
- 解凍したディレクトリ名を覚えておく(あとでインポートする)
Java パッケージ作成
Eclipse のプロジェクト・エクスプローラを使って, Java パッケージを作成します. Java パッケージ名には hoge.hoge.com のようなドメイン名を付ける習慣があることに注意してください. このページでは,作成するJava パッケージ名は,hoge.hoge.com と書く. (Java パッケージ名を変えるときは,読み替えてください).
- (もし,プロジェクト・エクスプローラが開いていなければ)プロジェクト・エクスプローラを開く
「ウインドウ」→「ビューの表示」→「プロジェクト・エクスプローラ」 と操作する.
Java パッケージの作成,クラスの作成などの作業は,プロジェクト・エクスプローラで行う.
- Java パッケージを新規作成すべきプロジェクトの選択
プロジェクト・エクスプローラに,プロジェクト一覧が表示されているはずです. Java パッケージを新規作成したいプロジェクト名 HLgame を右クリックして, 「新規」→「パッケージ」と操作する.
- Java パッケージ名の指定
「Java パッケージ (Java package)」の名前は,Java パッケージ名 hoge.hoge.comを記入する.その後,「終了」をクリック.
Apache Struts2 ファイルのインポート
- いま作成したプロジェクトのWEB-INF/libを右クリックし、「インポート」を選ぶ
- 「一般」を展開し「ファイルシステム」を選ぶ
- 先ほど Apache Struts2 を展開したディレクトリ選ぶ
jar ファイルが入っているディレクトリを選ぶ
クラス定義
5つのクラス StartAction, HighAndLowAction, HighAndLowForm, HighAndLowData, BusinessLogic.java
- プロジェクト・エクスプローラで, プロジェクト名の下の 「Java リソース; src」または「src」の下を展開すると,Java パッケージ名 hoge.hoge.com が出ます.
- Java パッケージ名 hoge.hoge.com を右クリックして,クラス作成
- StartAction クラス
- HighAndLowAction クラス
- HighAndLowForm クラス
- HighAndLowData クラス
- BusinessLogic クラス
◆上記の5つのクラスを作成し終わったところ
- プロジェクト・エクスプローラで,クラスの「クラス名.java 」をダブルクリック すると,エディタが開きます.下記のプログラムを,カット&ペースト.
StartAction.java
----------------------ここから---------------------- package hoge.hoge.com; 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 javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; // アクション・クラス public class StartAction extends Action { public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception{ // // ゲーム開始 // HttpSession session = request.getSession(); //システム内部状態オブジェクトを作成.セッション変数に保存 HighAndLowData highAndLowData = new HighAndLowData(); highAndLowData.reset(); session.setAttribute("data", highAndLowData); // ビジネスロジックオブジェクトを作成 BusinessLogic businessLogic = new BusinessLogic(); businessLogic.setHighAndLowData(highAndLowData); businessLogic.startHighAndLowGame(); return mapping.findForward("success"); } } ----------------------ここまで----------------------
HighAndLowAction.java
----------------------ここから---------------------- package hoge.hoge.com; 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.ActionMessage; import org.apache.struts.action.ActionMessages; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; // アクション・クラス public class HighAndLowAction extends Action { public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception{ HttpSession session = request.getSession(); // システム内部状態オブジェクトは生成済み(のはず) HighAndLowData highAndLowData = (HighAndLowData)session.getAttribute("data"); // 入力フォームオブジェクトは,本メソッドのパラメータ HighAndLowForm highAndLowForm = (HighAndLowForm) form; // 実際の処理は,ビジネスモデルに依頼 BusinessLogic businessLogic = new BusinessLogic(); businessLogic.setHighAndLowData(highAndLowData); businessLogic.setHighAndLowForm(highAndLowForm); int betMoney=highAndLowForm.getBetMoney(); //賭け金が正しくない場合 if(betMoney > highAndLowData.getBalance()){ ActionMessages ms = new ActionMessages(); ActionMessage m = new ActionMessage("エラー:賭け金が所持金を超えています."); ms.add(ActionMessages.GLOBAL_MESSAGE, m); saveErrors(request, ms); return mapping.findForward("betmoneyfault"); } //Highが押された場合 else if(highAndLowForm.getSubmit().equals("High")){ boolean result = businessLogic.betHighResult(); //Highを選んだ場合の処理 businessLogic.choiceNextCard(); //次のカードを決定 //残金が0となった場合 if(!result){ return mapping.findForward("gameover"); } else { //highAndLowData = businessLogic.getHighAndLowData(); session.setAttribute("data", highAndLowData); return mapping.findForward("success"); } } //Lowが押された場合 else{ boolean result = businessLogic.betLowResult(); //Lowを選んだ場合の処理 businessLogic.choiceNextCard(); //次のカードを決定 //残金が0となった場合 if(!result){ return mapping.findForward("gameover"); } else { //highAndLowData = businessLogic.getHighAndLowData(); session.setAttribute("data", highAndLowData); return mapping.findForward("success"); } } } } ----------------------ここまで----------------------
HighAndLowForm.java
----------------------ここから---------------------- package hoge.hoge.com; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionErrors; import org.apache.struts.action.ActionMessages; import org.apache.struts.action.ActionMessage; import org.apache.struts.validator.ValidatorForm; import javax.servlet.http.HttpServletRequest; public class HighAndLowForm extends ValidatorForm { private int betMoney = 0; //賭け金 private String submit = null; //サブミットボタン public int getBetMoney() { return betMoney; } public void setBetMoney(int betMoney) { this.betMoney = betMoney; } public String getSubmit() { return submit; } public void setSubmit(String submit) { this.submit = submit; } public void reset(){ this.betMoney = 0; this.submit = null; } public ActionErrors validate(ActionMapping mapping, HttpServletRequest request){ ActionErrors errors = new ActionErrors(); // betMoney チェック if ( getBetMoney() <= 0) { errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("errors.detail", "「掛け金」 は必須です.範囲は1以上の整数です")); System.out.println("validate ERROR"); return errors; } return null; } } ----------------------ここまで----------------------
HighAndLowData.java
----------------------ここから---------------------- package hoge.hoge.com; public class HighAndLowData { private int previousCard; //前のカード private int nextCard; //次のカード private int balance; //残高 private int getMoney; //獲得金額 public int getPreviousCard() { return previousCard; } public void setPreviousCard(int previousCard) { this.previousCard = previousCard; } public int getNextCard() { return nextCard; } public void setNextCard(int nextCard) { this.nextCard = nextCard; } public int getBalance() { return balance; } public void setBalance(int balance) { this.balance = balance; } public int getGetMoney() { return getMoney; } public void setGetMoney(int getMoney) { this.getMoney = getMoney; } public void reset(){ this.previousCard = 8; this.nextCard = 1; this.balance = 10000; this.getMoney = 0; } } ----------------------ここまで----------------------
BusinessLogic.java
----------------------ここから---------------------- package hoge.hoge.com; public class BusinessLogic { /** * 内部状態を管理するクラス : HighAndLowData * * 残金の値を管理する変数 : balance * 賭け金の値を管理する変数 : betMoney * 前のカードの値を管理する変数 : previousCard * 次のカードの値を管理する変数 : nextCard */ private HighAndLowData highAndLowData = null; public void setHighAndLowData(HighAndLowData data){ this.highAndLowData = data; } public HighAndLowData getHighAndLowData(){ return this.highAndLowData; } /** * フォームのデータを管理するクラス : HighAndLowForm * * 賭け金の値を管理する変数 : betMoney */ private HighAndLowForm highAndLowForm = null; public void setHighAndLowForm(HighAndLowForm form){ this.highAndLowForm = form; } public HighAndLowForm getHighAndLowForm(){ return this.highAndLowForm; } /** * 持ち金の初期値 */ private int defaultBalance = 10000; /** * 内部状態に対する初期値の設定 */ public void startHighAndLowGame(){ int previousCard = ((int)(Math.random() * 12.99)) + 1; this.highAndLowData.setPreviousCard(previousCard); int nextCard = ((int)(Math.random() * 12.99)) + 1; this.highAndLowData.setNextCard(nextCard); this.highAndLowData.setBalance(defaultBalance); } /** * 次のカードを決定する関数 * doubule型のランダムな値を出力関数 Math.random() を使用し1~13の値を次のカードの値とする */ public void choiceNextCard(){ int nextCard = ((int)(Math.random() * 12.99)) + 1; this.highAndLowData.setPreviousCard(this.highAndLowData.getNextCard()); this.highAndLowData.setNextCard(nextCard); } /** * 2つのカードの大小関係を調べる関数 * このゲームでのカードの強さの関係 : 2 < 3 < ・・・ < 10 < J(11) < Q(12) < K(13) < A(1) * 返り値として正の値(1), 0, 負の値(-1)を返す * 1 : 実行した結果Highだった場合 * 0 : 実行した結果同じ数値だった場合 * -1 : 実行した結果Lowだった場合 */ private int compareTwoCards(){ int previousCard = this.highAndLowData.getPreviousCard(); int nextCard = this.highAndLowData.getNextCard(); // 2つのカードが同じ数値だった場合 if(previousCard == nextCard) return 0; // previousCardが 1 だった場合は無条件でLow if(previousCard == 1) return -1; // nextCardが 1 だった場合は無条件でLow if(nextCard == 1) return 1; // 両カードが2~13のどれかの値であるため単純な大小比較で判断 if(previousCard < nextCard) return 1; else return -1; } /** * Highを選択した結果変化する残高を計算する関数 * 賭け金 betMoney を引数として持つ * 返り値としてbooleanを返す * true : 実行した結果残金の値が残っている場合 * false : 実行した結果残金の値が0になった場合 */ public boolean betHighResult(){ int balance = this.highAndLowData.getBalance(); int betMoney = this.highAndLowForm.getBetMoney(); // 2つのカードの比較 int result = this.compareTwoCards(); // Highである場合(ユーザの勝ち) if(result == 1){ balance += betMoney; this.highAndLowData.setBalance(balance); this.highAndLowData.setGetMoney(betMoney); return true; } // 同じ又はLowである場合(ユーザの負け) else{ balance -= betMoney; this.highAndLowData.setBalance(balance); this.highAndLowData.setGetMoney(-betMoney); if(balance == 0) return false; else return true; } } /** * Lowを選択した結果変化する残高を計算する関数 * 賭け金 betMoney を引数として持つ * 返り値としてbooleanを返す * true : 実行した結果残金の値が残っている場合 * false : 実行した結果残金の値が0になった場合 */ public boolean betLowResult(){ int balance = this.highAndLowData.getBalance(); int betMoney = this.highAndLowForm.getBetMoney(); // 2つのカードの比較 int result = this.compareTwoCards(); // Lowである場合(ユーザの勝ち) if(result == -1){ balance += betMoney; this.highAndLowData.setBalance(balance); this.highAndLowData.setGetMoney(betMoney); return true; } // 同じ又はHighである場合(ユーザの負け) else{ balance -= betMoney; this.highAndLowData.setBalance(balance); this.highAndLowData.setGetMoney(-betMoney); if(balance == 0) return false; else return true; } } } ----------------------ここまで----------------------
JSPファイルの作成
3つのJSPファイル index.jsp, game.jsp, gameover.jsp を作成する.
Struts のタグを使う. Struts のタグについては, Struts のタグ一覧 を参考にして下さい.
- プロジェクト・エクスプローラで,
プロジェクト名 HLgame の下の 「WebContentを展開しておく
- WebContent を右クリックして,3つの JSP ファイルを作成.
- index.jsp
- game.jsp
- gameover.jsp
- 生成したJSPファイルの確認
- プロジェクト・エクスプローラで,JSP ファイルをダブルクリック すると,エディタが開きます.下記のプログラムを,カット&ペースト.
index.jsp
----------------------ここから---------------------- <%@ page contentType="text/html; charset=utf-8" %> <%@ taglib uri="/tags/struts-bean" prefix="bean" %> <%@ taglib uri="/tags/struts-logic" prefix="logic" %> <%@ taglib uri="/tags/struts-html" prefix="html" %> <%@ taglib uri="/tags/struts-nested" prefix="nested" %> <html:html> <head> <meta http-equiv="Content-Type" content="text/html; charset=Shift-JIS"/> <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="Windows-31J" %> <title>Game Start</title> </head> <body> <html:form method="POST" action="/startAction"> <html:submit property="submit" value="GameStart"/> </html:form> </body> </html:html> ----------------------ここまで----------------------
game.jsp
----------------------ここから---------------------- <%@ page contentType="text/html; charset=utf-8" %> <%@ taglib uri="/tags/struts-bean" prefix="bean" %> <%@ taglib uri="/tags/struts-logic" prefix="logic" %> <%@ taglib uri="/tags/struts-html" prefix="html" %> <%@ taglib uri="/tags/struts-nested" prefix="nested" %> <html:html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="Windows-31J" %> <title>High and Low Game</title> </head> <body> <html:form method="POST" action="/highAndLowAction"> <center> <h1>High And Low Game</h1> <h4>〜ルール〜</h4> <table summary="ゲーム説明"> <tr align=left> <td> <table border=1 summary="ルール" cellspacing=5 cellpadding=3 bordercolor="#000000"> <tr> <td><ul> <li> 次に引くカードの値が前のカードの値よりも高い(High)か低い(Low)かを当てるゲーム.<br> どちらかにお金を賭けて,当たりであれば賭け金は倍になって戻ってくる.<br> ハズレであれば賭け金は失なわれる.<br><br></li> <li>カードの値の高い・低いは以下の通り <ul><li>【高い】 1 > 13 > 12 > ・・・ > 3 > 2 【低い】</li></ul> </li></ul> </td></tr> </table> </td> </tr> <tr><td><br></td></tr> <tr align=left><td> <ol> <li>賭け金を設定してください</li> <li>【High】か【Low】かを選び,選んだ方のボタンを押してください</li> </ol> <logic:messagesPresent> <STRONG>入力内容が正しくない場合,ゲームができませんので,正しくご入力ください</STRONG> <html:messages id="msg" message="false"> <li style="color: red"><bean:write name="msg" /></li> </html:messages> </logic:messagesPresent> </td></tr> </table> <br> <table border=1 cellpadding=3 width=260 summary="ゲームテーブル"> <tr align=center> <td>前のカード</td> <td> <table border=1 width=20pt cellspacing=0 bordercolor="#000000" summary="前のカード"> <tr align=center> <td><bean:write name="data" property="previousCard"/></td> </tr> </table> </td> </tr> <tr align=center> <td>次のカード</td> <td> <table border=1 width=20pt cellspacing=0 bordercolor="#000000" summary="次のカード"> <tr align=center> <td>?</td> </tr> </table> </td> </tr> <tr align=center> <td>賭け金</td> <td> <input type="text" name="betMoney" style="text-align:right" size=15/> </td> </tr> <tr align=center> <td rowspan="2"> High<br>or<br>Low</td> <td> <html:submit property="submit" value="High"/> </td> </tr> <tr align=center> <td> <html:submit property="submit" value="Low"/> </td> </tr> <tr align=center> <td>残金</td> <td align=right> <bean:write name="data" property="balance"/> </td> </tr> <tr align=center> <td>前回の獲得金額</td> <td align=right> <bean:write name="data" property="getMoney"/> </td> </tr> </table> </center> </html:form> </body> </html:html> ----------------------ここまで----------------------
gameover.jsp
----------------------ここから---------------------- <%@ page contentType="text/html; charset=utf-8" %> <%@ taglib uri="/tags/struts-bean" prefix="bean" %> <%@ taglib uri="/tags/struts-logic" prefix="logic" %> <%@ taglib uri="/tags/struts-html" prefix="html" %> <%@ taglib uri="/tags/struts-nested" prefix="nested" %> <html:html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>Game Over</title> </head> <body> <h1 align=center>GAME OVER</h1> </body> </html:html> ----------------------ここまで----------------------
WebContet\WEB-INF\lib\struts-config.xml
すでに存在する WebContet\WEB-INF\lib\struts-config.xml を,次のものに置き換え
- struts-config.xmlを開く.
プロジェクトを展開,WEB-INF を展開.struts-config.xml を右クリック. 「アプリケーションから開く」→「struts-config.xmlエディタ」
- ソースエディタに切り替え
struts-config.xmlエディタでは, 「フロー」,「ソース」の2つのタブがある. 「ソース」をクリックして,ソースエディタに切り替える.
- カット&ペースト
----------------------ここから---------------------- <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd"> <struts-config> <data-sources> </data-sources> <form-beans> <form-bean name="highAndLowForm" type="hoge.hoge.com.HighAndLowForm"/> </form-beans> <global-exceptions> </global-exceptions> <global-forwards> </global-forwards> <action-mappings> <action path="/highAndLowAction" name="highAndLowForm" type="hoge.hoge.com.HighAndLowAction" scope="session" validate="true" input="/game.jsp"> <forward name="success" path="/game.jsp"/> <forward name="betmoneyfault" path="/game.jsp"/> <forward name="gameover" path="/gameover.jsp"/> </action> <action path="/startAction" name="highAndLowForm" type="hoge.hoge.com.StartAction" scope="session" validate="false" input="/index.jsp"> <forward name="success" path="/game.jsp"/> </action> </action-mappings> <controller processorClass="org.apache.struts.tiles.TilesRequestProcessor"/> <message-resources parameter="MessageResources"/> <plug-in className="org.apache.struts.tiles.TilesPlugin"> <set-property property="definitions-config" value="/WEB-INF/tiles-defs.xml"/> <set-property property="moduleAware" value="true"/> </plug-in> <plug-in className="org.apache.struts.validator.ValidatorPlugIn"> <set-property property="pathnames" value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/> </plug-in> </struts-config> ----------------------ここまで----------------------
WebContet\WEB-INF\lib\validation.xml
すでに存在する WebContet\WEB-INF\lib\validation.xml を,次のものに置き換え
----------------------ここから--------------------- <?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE form-validation PUBLIC "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.1.3//EN" "https://jakarta.apache.org/commons/dtds/validator_1_1_3.dtd"> <form-validation> <global> </global> <formset> <form name="highAndLowForm"> <field property="betMoney" depends="required,intRange"> <!-- return "Bet Money is required." --> <msg name="required" key="errors.required"/> <arg0 key="Bet Money" resource="false"/> <!-- return "Bet Money is not in the range 0 through Balance." --> <msg name="intRange" key="errors.range"/> <arg0 key="Bet Money" resource="false"/> <arg1 key="1" resource="false" /> <arg2 key="Balance" resource="false" /> <!-- range setting --> <var> <var-name>min</var-name> <var-value>1</var-value> </var> <var> <var-name>max</var-name> <var-value>2147483647</var-value> </var> </field> </form> </formset> </form-validation> ----------------------ここまで----------------------
Struts サンプルプログラムのテスト実行
Eclipse のプロジェクト・エクスプローラを使用して,テスト実行を行ってみる.
- Eclipse のプロジェクト・エクスプローラで,プロジェクト名 HLgame を右クリック
- 「実行 (Run As)」→「サーバーで実行 (Run on Server)」と操作
- Eclipse 内部の tomcat サーバ: が起動(または,再起動)する(結果は,コンソール・ビューに表示される).
- 実行結果の確認
Eclipse の 組み込み Web ブラウザ (Internal Web ブラウザ)が開き,そこに実行結果が出る.
このウインドウに,index.jsp の表示結果が出れば成功.
Internal Web ブラウザ内のアドレスバーの部分は,
http://localhost:8080/HLgame/
のようになっていることを確認しておきます
アクション単位での実行
Tomcatサーバを起動し, Webブラウザで,URL として,「http://localhost:8080/プロジェクト名/任意のアクション名.do」を指定. これで,アクション名を直接指定しての実行ができる.validate メソッドによる妥当性検証
上記のプログラムでは, アクションフォーム・ビーンの validate メソッドを使って, 「掛け金」が1以上であることを検証している.
アクションフォーム・ビーンでの妥当性検証は,入力データとして妥当かのチェックです. 業務ルール的なエラーのチェックです.例えば,持ち金以上を掛け金にできない,という業務ルールのチェックは, アクションフォーム・ビーンでは無く,アクション・クラスで行うことになる.
妥当性検証では,必須属性(空であることを許さない),範囲(○○以上○○以下の整数など),文字列長(最小○○文字,最大○○文字など)などのチェックを行うことになる.
- validate メソッド
public ActionErrors validate(ActionMapping mapping, HttpServletRequest request){ ActionErrors errors = new ActionErrors(); // betMoney 範囲チェック if ( getBetMoney() <= 0) { errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("errors.detail", "「掛け金」 は必須です.範囲は1以上の整数です")); return errors; } return null; }
アクションフォームビーンに格納された値は, validate メソッドで妥当性が検証されます. つまり,validate メソッドを自前で書いておくと,アクションの呼び出しの前に,妥当性検証が自動的に行われます.エラーがあれば,アクションが呼び出されません. validate メソッドの書き方は,上記のようになる.
文字列のチェックであれば,equals(""), isBlankOrNull などを使うことになるでしょう.
- game.jsp
<logic:messagesPresent> <STRONG>入力内容が正しくない場合,ゲームができませんので,正しくご入力ください</STRONG> <html:messages id="msg" message="false"> <li style="color: red"><bean:write name="msg" /></li> </html:messages> </logic:messagesPresent>
エラーメッセージの表示について記述します.
- (参考) struts-config.xml
action 要素の input 属性で,エラー時の遷移先(JSP)を指定します.
- (参考) MessageResource.properties
エラーメッセージ表示に関する設定ファイル

参考Webページ, The Apache Struts Web Application Framework (Struts 提供元): https://jakarta.apache.org/struts/index.html
参考Webページ, The Ja-Jakarta Project Struts翻訳 (Ja-Jakarta Project による Struts ドキュメントの翻訳): http://www.ingrid.org/jajakarta/struts/