Struts とは,Web アプリケーション開発のフレームワークです. Apache Jakarta プロジェクトの成果物です.
このページでは,Eclipse の機能を使いながら,Struts フレームワークに準拠した Java サーブレット・プログラムを開発(設計と実装)する手順を説明する. さらに,Eclipse で, 出来たJava サーブレット・プログラムを,Tomcat 上で動作させます. 以上のことを,プロラムの見本と,操作手順の図解で説明する.
※ Tomcat と Java サーブレット・プログラムの全般については,別の Web ページを見てください.
【この Web ページの目次】
【補足説明】
下記の 2つのサーバは別物です. 2つを同時に動かすことはできません(ポートを奪い合うことができないので).一方を動かすときは,もう一方を止めることになる.
Eclipse では,Eclipse 内部の Tomcat サーバが動き, Java サーブレットの動作テストなどに使う.
Eclipse とは無関係の Tomcat サーバ(C:\tomcat55\bin\tomcat5w.exe で起動する Tomcat サーバのこと).当然, 公開 tomcat サーバが管理するディレクトリも Eclipse とは無関係.
※ なお,「Eclipse 内部の tomcat サーバ」を使えるようするには, Eclipse で「新規サーバの定義」という操作を行う必要がある.これは,1回行うだけで十分です.
次のものが出てきます. 練習の目的は,それぞれの役割と,互いの関係を理解することです.
Web ブラウザに表示されるページのデザインと中身(フォーム,動的データなど)が定義される.
JSP プログラムは,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 リクエストの期間を超えて共有される.
画面遷移,アクションマッピング,アクションフォワードに関する定義が行われている設定ファイル.
HTTP リクエスト処理のためにアクションマッピング(HTTPリクエストと,特定のアクション・クラスの execute メソッドとのマッピング)と, アクションフォワードにおける,JSP プログラムのフォワード(Struts アクションマッピングオブジェクトと JSP プログラムとのマッピング)
入力フォームに記入されるべきフォームデータの各項目について,データの種類や制約が記述されたファイル. データの種類や制約が満足されていることが自動的に検証され,エラーがあれば,所定の処理が行われる.
Struts フレームワークが有するアクションサーブレットが,クライアントからの要求(HTTPリクエスト)を,適切な Struts アクション・クラスに委譲する. (所定の Struts アクション・クラスの execute メソッドが呼び出される). 同時に,フォームデータを,Struts アクションフォーム・ビーンに格納する. このとき,Struts アクションフォーム・ビーンの validate メソッドも使い,入力データの検証が行われる (これは,validation.xml による検証と別のもので,validation.xml では出来ない細かなエラー処理ができる).
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 ビーンのクラスに実装される.
アクションフォーム・ビーンを private メンバ属性として保持する(アクションフォーム・ビーンを,セッターを使って設定するのは,Struts アクション・クラスの役目である) ビジネスロジックを提供する Java ビーンにおける処理結果は,別の Java ビーン・オブジェクトに格納される.
※ Ubuntu の場合には「Ubuntu で Tomcat バージョン 7 のインストールとテスト実行」を参考にしてください
前もって,Tomcat のバージョンを調べておいて下さい
前もって,Tomcat インストールディレクトリを調べておいてください.このページでは,次のように書く.
以下,Eclipse を使う. プロジェクトの作成,クラスの定義と実行という一連の操作を,図解で説明する.
Java サーブレット・プログラムを動かすために,Eclipse のプロジェクト等を作る. Web ページでは,プロジェクト名,Java パッケージ名は次のように記述します. (すでに同じ名前のプロジェクトがある,といったときは,プロジェクト名を変えてください).
Struts を使う上で,作業場の重要な点(忘れやすい点)は,次の2つです.忘れずに行うこと.
ここでは,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の関係は次のようになっています.
下記の手順で,動的 Web プロジェクトを新規に作成する.
「ウインドウ (Window)」→「ビューの表示 (Show View)」→「プロジェクト・エクスプローラ (Project Explorer)」 と操作する.
「ファイル」→「新規 (New)」→「プロジェクト (Project)」
または,プロジェクト・エクスプローラ内で,右クリック→「新規 (New)」→「プロジェクト (Project)」
新規プロジェクトのウインドウが開くので, 「Web」を展開する.
展開した「Web」の下にある 「動的 Webプロジェクト (Dynamic Web Project)」を選び, 「次へ」をクリック
設定用のウインドウが開くので,下記の設定を行う. 設定が終わったら,「次へ」をクリック.
プロジェクト名は,好きな名前でよいが,スペースや全角文字は避けること. ここでは,プロジェクト名を,「HLgame」と付けることにする.
「デフォルトの使用 (Use default)」にチェックを入れたままで良い.
バージョンが違う場合、「なし」になっている場合は、正しいバージョン(例えば「Apache Tomcat v5.5」)に変更しておく
※ 変更のとき,「なし」だけしか無くて,「Apache Tomcat v5.5」などが候補として表示されない場合は, 「Eclipse を使用しての Java サーブレット・プログラムの開発」の Web ページに記載の「新規サーバの定義」を行うこと.
「次へ」をクリック.
※ このウインドウが開かないことがある.気にしなくてよい.
「web.xml デプロイメント記述子の生成」をチェックし、 「終了」をクリック.
※ このウインドウが開かないことがある.気にしなくてよい.
Eclipse 3.X を使用していて、StrutsIDE をインストールしている場合には、 次の手順で、「動的 Web プロジェクトへの Struts サポートの追加 」を行うことができる.
「その他」→「Amateras」→「Struts」→「Strutsサポートの追加」と操作し, 「次へ」をクリック.
「Strutsサポートの追加」が出てこないときは, Eclipse StrutsIDE プラグイン の手順を行った後に, ここの手順を繰り返す.
Webアプリケーションのルートが,<プロジェクト名>/WebContent のようになっていることを確認.
なっていなければ,Web アプリケーションのルートを,<プロジェクト名>/WebContent のように設定
(<プロジェクト名>/WebContent の設定を忘れたら,プロジェクトの作成からやり直し)
Struts用のJARファイルが設定されるとともに,各種設定ファイルのひな型が生成される.
XML ファイルとJSPファイルのエディタは,デフォルトでは WTP のエディタになっている.デフォルト以外のエディタで開きたいときは, XML ファイルとJSPファイルを右クリックして,エディタを選べる.
http://struts.apache.org/development/2.x/
◆ Ubuntu での操作手順例
unzip struts-2.3.15.3-all.zip
◆ Ubuntu での操作手順例
Eclipse のプロジェクト・エクスプローラを使って, Java パッケージを作成します. Java パッケージ名には hoge.hoge.com のようなドメイン名を付ける習慣があることに注意してください. このページでは,作成するJava パッケージ名は,hoge.hoge.com と書く. (Java パッケージ名を変えるときは,読み替えてください).
「ウインドウ」→「ビューの表示」→「プロジェクト・エクスプローラ」 と操作する.
Java パッケージの作成,クラスの作成などの作業は,プロジェクト・エクスプローラで行う.
プロジェクト・エクスプローラに,プロジェクト一覧が表示されているはずです. Java パッケージを新規作成したいプロジェクト名 HLgame を右クリックして, 「新規」→「パッケージ」と操作する.
「Java パッケージ (Java package)」の名前は,Java パッケージ名 hoge.hoge.comを記入する.その後,「終了」をクリック.
jar ファイルが入っているディレクトリを選ぶ
5つのクラス StartAction, HighAndLowAction, HighAndLowForm, HighAndLowData, BusinessLogic.java
◆上記の5つのクラスを作成し終わったところ
----------------------ここから---------------------- 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"); } } ----------------------ここまで----------------------
----------------------ここから---------------------- 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"); } } } } ----------------------ここまで----------------------
----------------------ここから---------------------- 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; } } ----------------------ここまで----------------------
----------------------ここから---------------------- 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; } } ----------------------ここまで----------------------
----------------------ここから---------------------- 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; } } } ----------------------ここまで----------------------
3つのJSPファイル index.jsp, game.jsp, gameover.jsp を作成する.
Struts のタグを使う. Struts のタグについては, Struts のタグ一覧 を参考にして下さい.
----------------------ここから---------------------- <%@ 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> ----------------------ここまで----------------------
----------------------ここから---------------------- <%@ 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> ----------------------ここまで----------------------
----------------------ここから---------------------- <%@ 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 を,次のものに置き換え
プロジェクトを展開,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 を,次のものに置き換え
----------------------ここから--------------------- <?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> ----------------------ここまで----------------------
Eclipse のプロジェクト・エクスプローラを使用して,テスト実行を行ってみる.
Eclipse の 組み込み Web ブラウザ (Internal Web ブラウザ)が開き,そこに実行結果が出る.
このウインドウに,index.jsp の表示結果が出れば成功.
Internal Web ブラウザ内のアドレスバーの部分は,
http://localhost:8080/HLgame/
のようになっていることを確認しておきます
上記のプログラムでは, アクションフォーム・ビーンの validate メソッドを使って, 「掛け金」が1以上であることを検証している.
アクションフォーム・ビーンでの妥当性検証は,入力データとして妥当かのチェックです. 業務ルール的なエラーのチェックです.例えば,持ち金以上を掛け金にできない,という業務ルールのチェックは, アクションフォーム・ビーンでは無く,アクション・クラスで行うことになる.
妥当性検証では,必須属性(空であることを許さない),範囲(○○以上○○以下の整数など),文字列長(最小○○文字,最大○○文字など)などのチェックを行うことになる.
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 などを使うことになるでしょう.
<logic:messagesPresent> <STRONG>入力内容が正しくない場合,ゲームができませんので,正しくご入力ください</STRONG> <html:messages id="msg" message="false"> <li style="color: red"><bean:write name="msg" /></li> </html:messages> </logic:messagesPresent>
エラーメッセージの表示について記述します.
action 要素の input 属性で,エラー時の遷移先(JSP)を指定します.
エラーメッセージ表示に関する設定ファイル
参考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/