■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 2008年05月25日 楽しいJava講座 - 初心者から達人へのパスポート vol.105 セルゲイ・ランダウ バックナンバー: http://www.flsi.co.jp/Java_text/ ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ [このメールマガジンは、画面を最大化して見てください。] ======================================================== ◆ 01.Strutsのアプリケーション開発 ======================================================== さて、ここには以下のようなソース・コードのファイルがリスト されていますね。 JavaServer Pages Simple.jsp SimpleResults.jsp Actions SuccessAction.java ProcessSimpleAction.java ActionForm SimpleActionForm.java Configuration files struts-config.xml これらのファイルは、Strutsのユーザー(Strutsを使ってWebアプリ ケーションを開発する人)が実際に作成しなければならないファイル です。 (ただし、ファイル名はアプリケーションで独自に命名しますので、 これらと同じファイル名が使われるということではありません。) そして、これらのうちJavaServer Pages、すなわちJSPは、これまでの Webアプリケーションのときと同じくWebページを表示するためのファイル (JSPのファイルがHTMLに変換されてWebブラウザーに返される)で、 新しく登場してきたActionというのはWebアプリケーションの処理の流れ をコントロールするためのクラスで、同じくActionFormはWebページの FORMのデータを保持するためのクラスで、Configuration file(構成ファ イル)(struts-config.xml)というのは、これらのファイルの関係(構成) を記述するファイルです。 では、まず最初に、これらのサンプル・ファイルを使ってStrutsの 仕組みを大まかに説明しておきましょう。 その前に、struts-cookbook-1.3.8フォルダーの下のWEB-INFフォルダー、 つまり C:\Tomcat6.0\webapps\struts-cookbook-1.3.8\WEB-INF の中にある web.xml を確認してください。web.xmlというのは、以前出てきたWebアプリ ケーション・デプロイメント記述子(Web Application Deployment Descriptor)でしたね。 このweb.xmlをテキスト・エディター(NoEditorなど)で開いて見て ください。 -------------------------------------------------------- <servlet> <servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <init-param> <param-name>config</param-name> <param-value> /WEB-INF/struts-config.xml, /WEB-INF/struts-config-Wildcard.xml </param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet> <!-- Standard Action Servlet Mapping --> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> -------------------------------------------------------- という部分がありますが、この部分は今後、我々がStrutsのアプリケーション を作っていくときにもそのまま使用することになります。 ここに書いてあることを日本語に翻訳(?)すると、まず <servlet> <servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <init-param> <param-name>config</param-name> <param-value> /WEB-INF/struts-config.xml, /WEB-INF/struts-config-Wildcard.xml </param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet> の部分は、org.apache.struts.action.ActionServletというクラスをactionという サーブレット名(servlet-name)で呼ぶことを指定しています。また、init-param というタグによって、(サーブレットが初めて呼ばれるときに行われる)初期化の ときに、(configというパラメーター名で読み込まれる)構成ファイルとしては、 /WEB-INF/struts-config.xmlと/WEB-INF/struts-config-Wildcard.xmlを読み込む ことを指定しています。 そして、 <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> の部分は、*.doすなわち、何とかかんとか.doというURLで呼び出されたときには、 このactionというサーブレットを呼び出すことを指定しています。(ここの*は「任意 の文字列」を意味します。) Strutsで使われるサーブレットは、このActionServletひとつだけです。 他に複数のサーブレットを使うように指定することも可能ですが、通常は その必要はありません。 そして、このActionServletは、Strutsによって実装済みであり、我々が実装 する必要はありません。 このActionServletが呼び出されると、さきほどのconfigというパラメーターで指定 されていたstruts-config.xml(とstruts-config-Wildcard.xml)というファイルを 見て(というか、もっと正確には、これらのファイルの内容はサーブレットの初期化 の段階でメモリー上に読み込まれているので、あとはメモリー上から情報を読み取っ て)、URLに対応付けられたファイルを探します。 ここらへんの動きを具体的に見ていくために、前回Webブラウザーに指定したURL http://localhost:8080/struts-cookbook-1.3.8/index.jsp の末尾で指定したindex.jspというJSPファイルの中身を見てみましょう。 ┌補足─────────────────────────┐ web.xmlの下のほうに記述されている <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> という指定は、URLでindex.jspの部分を省略しても、自動的に index.jspを呼び出してWebページを返してくれることを意味し ます。したがって、 http://localhost:8080/struts-cookbook-1.3.8/index.jsp の代わりに http://localhost:8080/struts-cookbook-1.3.8/ というURLで呼び出してもindex.jspのWebページが返ってくるの です。 └───────────────────────────┘ C:\Tomcat6.0\webapps\struts-cookbook-1.3.8\index.jsp をテキスト・エディターで開いて見てください。 この中の59行目の <html:link action="/prepareSimple">Execute</html:link> という部分が、前回、我々がクリックしたExecute(vol.104の最後のほうの(4)で クリックした部分)を表示するソース・コードです。 このhtml:linkというタグについては、後ほど詳しく説明しますが、ここでは action="/prepareSimple"という記述に注目してください。この記述があると、 表示されたExecuteという文字列をクリックすると、URLに/prepareSimple.do (後ろに.doが自動的に付加される)というのが指定されてサーブレットが呼び 出されるようになっています。 実際に前回の操作(Executeという文字列をクリックする)を再度行ってみて ください。Webブラウザーに http://localhost:8080/struts-cookbook-1.3.8/prepareSimple.do というURLが自動的に指定されることに気づくでしょう。 このURLが指定されると、さきほどのActionServletが呼び出され(*.doというURL ですからね)、ActionServletはstruts-config.xmlの中を見て(正確にはメモリー の中を見るのだが)prepareSimpleというパス(path)の記述を探してきます。 実際にstruts-config.xmlの中を見る(最初のリストの中にあるstruts-config.xml をクリックするか、もしくは、 C:\Tomcat6.0\webapps\struts-cookbook-1.3.8\WEB-INF\struts-config.xml を直接テキスト・エディターで開いて見てください)と、 -------------------------------------------------------- <action path="/prepareSimple" type="examples.SuccessAction"> <forward name="success" path="/jsp/simple/Simple.jsp"/> </action> -------------------------------------------------------- という行が見つかりますね。この行は、「/prepareSimpleというパスがURLに指定 されていたらexamples.SuccessActionというクラスを呼び出し(そのexecuteという メソッドを実行し)、その結果forwardに"success"という文字列が設定されたら、 /jsp/simple/Simple.jspというJSPファイルを結果のWebページとしてWebブラウザー に返しなさい。」ということを指定しています。(このforwardとは何なのか? については、後で説明します。) したがって、この行を読み取ったActionServletはexamples.SuccessActionという クラス(のexecuteというメソッド)を呼び出して、その実行結果(戻り値)を判定し、 forwardに"success"という文字列が設定されていたら/jsp/simple/Simple.jspから 変換したWebページをWebブラウザーに返すのです。 では、そのSuccessActionというクラスのソース・コードを開いて見てみましょう。 (最初のリストの中にあるSuccessAction.javaをクリックする。) この中には、 -------------------------------------------------------- public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { return mapping.findForward("success"); } -------------------------------------------------------- という行がありますね。つまり、このSuccessActionのexecuteは mapping.findForward("success")という値を戻り値として返すという 処理をしています。 これが、先ほど言った「forwardに"success"という文字列を設定して 返す」という処理です。(これは極めて単純なサンプルなので、こんな 単純な処理しかしていませんが、普通のアプリケーションではもっと 複雑な処理をします。) なお、このSuccessActionはActionクラスのサブクラスとして作られている、つまり -------------------------------------------------------- public class SuccessAction extends Action { -------------------------------------------------------- という行があることも、ひとまず頭に入れておいてください。 (先ほどのActionServletと、このActionを混同しないでください。この Actionクラスのほうはサーブレットではなく、サーブレットによって呼び出さ れるオブジェクトです。) ActionServletはActionオブジェクト(これにはActionのサブクラスのオブジェク トも含まれる)のexecuteメソッドを実行して、その戻り値(ActionMapping型) を受け取り、戻り値(ActionMapping型オブジェクト)のforwardフィールドの値を struts-config.xmlの中のforwardタグのname属性、すなわち、先ほどの <forward name="success" path="/jsp/simple/Simple.jsp"/> という行に記述されている"success"という値と照合して、一致していれば /jsp/simple/Simple.jspから作成したWebページに遷移しようとします。 この、ActionMappingオブジェクトのforwardフィールドに値を設定するため のメソッドが先ほどのfindForwardというメソッドです。 なお、Actionオブジェクトのexecuteメソッドの処理結果によって"success"以外の 値を返す場合には、struts-config.xmlの中にそのためのforwardタグを追加して おく必要があります。 たとえば、 -------------------------------------------------------- <action path="/prepareSimple" type="examples.SuccessAction"> <forward name="success" path="/jsp/simple/Simple.jsp"/> <forward name="tano_baai" path="/jsp/simple/TaNoBaai.jsp"/> </action> -------------------------------------------------------- というような感じになります。 では、/jsp/simple/Simple.jspのソース・コードを見てみましょう。 今までに出てこなかった新しいタグがいっぱい使われていますね。これらはJSPの カスタム・タグ・ライブラリーという機能を使ってStrutsが独自に定義したタグ がふんだんに使われているのですが、詳しいことは後で説明することにします。 今回は、とりあえず -------------------------------------------------------- <html:form action="/processSimple"> <p>* What's your first name?:<br/><html:text property="name" size="40" maxlength="50"/></p> <p>* Enter a secret word or phrase:<br/><html:password property="secret" size="40" maxlength="50"/></p> <p>What is your favorite color?:<br/> <html:select property="color"> <html:option value="red">Red</html:option> <html:option value="green">Green</html:option> <html:option value="blue">Blue</html:option> </html:select> </p> <p><html:checkbox property="confirm"/>Is that really your favorite color?</p> <p>How much do you like your chosen color?:<br /> <html:radio property="rating" value="1">Actually, I hate it.</html:radio><br /> <html:radio property="rating" value="2">Not so much.</html:radio><br /> <html:radio property="rating" value="3">I'm indifferent</html:radio><br /> <html:radio property="rating" value="4">It's pretty neat</html:radio><br /> <html:radio property="rating" value="5">I painted my whole house with it.</html:radio> </p> <p>Enter a message (you may use html tags):<br /> <html:textarea property="message" cols="40" rows="6"/> </p> <html:hidden property="hidden" value="Sssh! It's a secret. Nobody knows I'm here."/> <hr noshade="noshade" /> <p> <html:submit> <bean:message key="button.submit" /> </html:submit> <html:cancel/> </p> </html:form> -------------------------------------------------------- の部分に注目してください。ここでhtml:formというタグはHTMLのFORMタグに相当 するStruts専用のタグです。また、html:textというタグはHTMLのINPUT type="text" に相当するStruts専用のタグです。また、html:submitやhtml:cancelというタグは、 HTMLのINPUT type="button"に相当するStruts専用のタグです。 そうやって見ていくと、何となくこれらの行の意味がわかってくるのではないで しょうか。詳しいことは後で説明することにしても、とりあえず What's your first name?: という文字列が並んでいるあたりから、前回、適当に自分の名前(英文字で)の入力 や選択などを行ったページの内容であることがわかりますね。 このWebページで入力を行った後、submitボタンをクリックすると、 <html:form action="/processSimple"> という行で指定されている/processSimpleという文字列にしたがって、/processSimple.do がURLの末尾に設定されてActionServletが呼び出されることになります(URLとしては action属性の値にさらに.doが付加されます)。 すると、ActionServletは、/processSimpleというパスを、またまたstruts-config.xml の中から探して来ます。 実際にstruts-config.xmlの中を見ると -------------------------------------------------------- <action path="/processSimple" type="examples.simple.ProcessSimpleAction" name="simpleForm" scope="request" input="/jsp/simple/Simple.jsp" cancellable="true" validate="true"> <forward name="success" path="/jsp/simple/SimpleResults.jsp"/> </action> -------------------------------------------------------- という行がありますね。 したがって、examples.simple.ProcessSimpleActionのexecuteメソッドが呼び出さ れることになります。 このとき同時に、 name="simpleForm" という行があることにも注目してください。 このsimpleFormという名前は、ずっと上のほうに <form-bean name="simpleForm" type="examples.simple.SimpleActionForm"/> というタグで定義されています。つまり、examples.simple.SimpleActionFormという クラス名のBeanにsimpleFormという名前を付けてあるのです。 そして、上のstruts-config.xmlの指定に従うと、このSimpleActionFormは、 requestオブジェクト(Webブラウザーから送られてきたデータを保持する HttpServletRequest型のオブジェクト)の中から取り出したFORMのデータを 取り込んだ状態でProcessSimpleActionのexecuteメソッドに(引数として)渡され ることになります。 (このexecuteメソッドの引数として渡す作業はActionServletが行ってくれます。) それともう一つ、 input="/jsp/simple/Simple.jsp" という行と validate="true"> という行にも注目してください。 このvalidate="true"というのは、さきほどのFORMのデータ(simpleFormオブジェクト) に対して、データの妥当性チェックを行うことを指定しており、 input="/jsp/simple/Simple.jsp"というのはその妥当性チェックの結果に問題(不正) があった場合の遷移先を指定しますが、これも後で説明します。 あと、 cancellable="true" というのは、cancelボタンを使ってキャンセルができるように指定するものです。 では、ProcessSimpleActionクラスのソース・コードを見てみましょう。 executeメソッドは -------------------------------------------------------- public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // If user pressed 'Cancel' button, // return to home page if (isCancelled(request)) { return mapping.findForward("home"); } // Forward to result page return mapping.findForward("success"); } -------------------------------------------------------- というようにコーディングされていますが、このうち引数の ActionForm form, というところに先ほどのsimpleFormオブジェクトが渡されます。(後でわかる ようにsimpleFormオブジェクト、すなわちSimpleActionFormクラスはActionForm のサブクラスとして作成されているものです。) そして、 if (isCancelled(request)) { return mapping.findForward("home"); } という行は、cancelボタンがクリックされた場合にforwardに"home"を設定 してreturnすることを指定しています。 また、cancelボタンがクリックされなかった場合(submitボタンがクリックさ れた場合)には、その下の return mapping.findForward("success"); が実行され、forwardに"success"が設定されてreturnすることになります。 では、再度struts-config.xmlの中を見てください。 -------------------------------------------------------- <global-forwards> <forward name="home" path="/Home.do"/> </global-forwards> -------------------------------------------------------- という行がありますね。このglobal-forwardsというのは、個別のactionタグに指定 されていないforward値に対して判定が下されるもので、ここではforward値が"home" のときには、URLに/Home.doを指定(forwardタグの中のpath属性の場合は現実のURL に即した記述が必要なので.doを付ける)してサーブレットを呼び出すことを指定 しています。 このURLの/Home.doに対して、ActionServletは、さらにその下にある -------------------------------------------------------- <action path="/Home" type="examples.SuccessAction"> <forward name="success" path="/index.jsp" redirect="true"/> </action> -------------------------------------------------------- という行を見つけて、examples.SuccessActionのexecuteメソッドを呼び出すことに なります。(actionタグの中のpath属性の場合は.doを付けない。) 一方、forward値が"success"の場合には、先ほどの -------------------------------------------------------- <action path="/processSimple" type="examples.simple.ProcessSimpleAction" name="simpleForm" scope="request" input="/jsp/simple/Simple.jsp" cancellable="true" validate="true"> <forward name="success" path="/jsp/simple/SimpleResults.jsp"/> </action> -------------------------------------------------------- の中にある <forward name="success" path="/jsp/simple/SimpleResults.jsp"/> の記述に従って、/jsp/simple/SimpleResults.jspが呼び出されてWebページが遷移 することになります。 SimpleResults.jspでは、先ほどのsimpleFormに保持されているFORMのデータを Webページに表示すべくStruts特有のタグがたくさん使われていますが、詳しい ことは後述します。 では、続いてSimpleActionFormクラスのソース・コードを見てみましょう。 (続く) では、今日はここまでにします。 何か、わからないところがありましたら、下記のWebページまで質問を お寄せください。 ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ★ホームページ: http://www.flsi.co.jp/Java_text/ ★このメールマガジンは 「まぐまぐ(http://www.mag2.com)」 を利用して発行しています。 ★バックナンバーは http://www.flsi.co.jp/Java_text/ にあります。 ★このメールマガジンの登録/解除は下記Webページでできます。 http://www.mag2.com/m/0000193915.html ★このメールマガジンへの質問は下記Webページにて受け付けて います。わからない所がありましたら、どしどしと質問をお寄 せください。 http://www.flsi.co.jp/Java_text/ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ Copyright (C) 2008 Future Lifestyle Inc. 不許無断複製 |