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/

