[[S2i18n]] *元文 [#ffa1fdf4] **S2Struts概要 [#ma39f73a] S2Strutsを使うと、S2とStrutsが簡単に連動するようになります。 Actionクラスにサービスコンポーネントが自動的に設定されるので、 Actionクラスの役割は適切なサービスコンポーネントを呼び出すだけになります。 Actionクラスはコントローラに徹することで、プレゼンテーション層とサービス層の役割分担も明確になります。また、Actionに対してAOPを適用することもできます。~ **S2Strutsリファレンス [#e48260ef] ***動作環境とEclipseプロジェクトのセットアップ [#mccd28f9] S2と同様にJDK1.4以上が必要です。~ S2StrutsVx.x.x.jarを解凍してできたs2strutsディレクトリをEclipseのJavaプロジェクトとして丸ごとインポートしてください。 .classpathを上書きするか聞かれるので、全て、はいのボタンをクリックして、全てを取り込みます。これで、私と全く同じ開発環境になります。 ~ サンプルは、 Tomcatと Tomcat Pluginを使うことを前提にしています。あらかじめインストールして置いてください。サンプルはS2StrutsExamleVx.x.x.jarとして別途用意されているので、ダウンロードして解凍してください。Eclipseでs2struts-exampleという名前でJavaプロジェクトを作成します。 Tomcatプロジェクトではないので気をつけてください。解凍してできたs2struts-exampleディレクトリを丸ごとインポートしてください。 .classpathを上書きするか聞かれるので、全て、はいのボタンをクリックして、全てを取り込みます。 s2struts-exampleプロジェクトを右クリックしてプロパティ->Tomcatを選びます。Tomcatプロジェクトであるをチェックし、アプリケーションURIを/s2struts-exampleとします。これで、Tomcatを再起動して、ブラウザからhttp://localhost:8080/s2struts-example/にアクセスすると四則演算のサンプルを見ることができます。~ ***基本的な使い方 [#e7ba40ec] まず、S2Containerを起動するためにS2StrutsServletをweb.xmlに登録する必要があります。また、S2ContainerFilterを以下のように設定して下さい。~ 次に、org.apache.struts.action.ActionServletの替わりに、org.seasar.struts.servlet.S2ActionServletを、 org.apache.struts.actions.RedeployableActionServletの替わりであれば、org.seasar.struts.servlet.S2RedeployableActionServletを、登録して下さい。 Strutsオリジナルのサーブレットを使用する場合は、struts-config.xmlにorg.seasar.struts.plugin.RegistActionClassPlugInを登録して下さい。~ ***web.xml [#a9631c80] [Code] 次に、S2とStrutsを連動させるために、S2用のRequestProcessorをstruts-config.xmlに登録する必要があります。 S2RequestProcessorとS2TilesRequestProcessorを用意しています。これらは、それぞれ、Strutsの、RequestProcessorとTilesRequestProcessorに相当します。~ ***struts-config.xml [#r24a5835] [Code] 上記のRequestProcessorから生成される全てのActionクラスがS2と連動するようになります。 RegistActionClassPlugInを登録する事により、S2と連動するActionを、明示的にコンポーネント定義に登録しておく必要はありません(Add.dicon)。インターフェースに対するセッターメソッドを定義しておけば、自動的にセッター・インジェクションが行われます。また、インターフェースのみが引数の、コンストラクタを定義している場合は、自動的に、コンストラクタ・インジェクションが行われます。~ ***Add.dicon [#ge5d01be] [Code] ただし、Actionに対して、AOPの適用や、 メソッド・インジェクションを行いたい場合、また、コンポーネントの依存関係が、型によって自動的に解決されない場合などには、他のコンポーネントと同様に、コンポーネント定義にActionクラスを登録しておく必要があります(Multiply.dicon)。~ ***Multiply.dicon [#u0bf3116] [Code] インスタンス属性は、任意です。このコンポーネント定義ファイルでは、では、他の演算サンプルとの比較のために、prototypeを指定しています。 singletonとするのであれば、明示的な指定の必要はありません。instance属性に、prototypeを指定をしていすると、 Actionクラスを、実装する時に、インスタンスフィールドを使用できるという利点があります。 ~ また、これらの定義ファイルは、アプリケーション全体の定義であるapp.diconに登録する必要があります。 ~ ***app.dicon [#cdac66da] [Code] サービスコンポーネントを受け取るためにActionクラスはコンストラクタもしくはセッターメソッドを定義しておきます。 execute()メソッドでは、サービスに処理を委譲するのみとなるので、非常にすっきりしたコードになっていることが分かると思います。~ ***AddAction [#h938d300] [Code] ***ActionをPOJOにした使い方 [#pc548494] org.apache.struts.action.Actionを継承しないPOJOをActionとして使用する事が出来ます。 ~ 以下のように、インターフェースと、実装クラスを作成し実装クラスは、コンポーネント定義ファイルに定義して下さい。アクションメソッドの戻り値は、Stringとして、forward名を返すようにして下さい。そして、struts-configには、インターフェースをactionタグのtype属性に指定して下さい。 ~ ***EchoAction [#x71de78f] [Code] ***EchoActionImpl [#dd87f3b9] [Code] POJOアクションクラスに、セッターメソッドがある場合、HttpServletRequestまたは、HttpSessionの値が、自動バインディングされます。~ (1)HttpServletRequest#getParameter(プロパティー名)~ (2)HttpServletRequest#getAttribute(プロパティー名)~ (3)HttpSession#getAttribute(プロパティー名)~ の優先順位で値を参照します。 ~ また、パラメーターに[]が付き、foo[0]=fooVal0,foo[1]=fooVal1のようなパラメーターを受け取った場合には、~ [Code] のように、第一引数にint、第二引数に値を持ったインデックス付きのセッターメソッドが自動バインディングの対象になります。~ また、getterメソッドがある場合も同様に、HttpServletRequestまたは、HttpSessionに値を自動バインディングします。~ (1)基本的に、HttpServletRequest#setAttribute(プロパティー名,プロパティー値)を行います。~ (2)HttpSession#setAttribute(プロパティー名,プロパティー値)を行いたい場合は、定数アノテーションにて、 ~ [Code] とActionクラスに記述する必要があります。 ~ ***Echo.dicon [#ua755073] [Code] ***struts-config.xml [#g6dee1e4] [Code] 実装クラスのプロパティーは、web.xmlにS2ContainerFilterを登録しておく事によって、リクエストまたは、セッションとActionに対し、相互に自動バインディングされます。リクエストとセッションのどちらにバインディングされるかは、コンポーネント定義ファイルのinstance属性により決定されます。ActionFormに関しては、struts-config.xmlに定義したscope属性により決定します。 ~ また、インターフェースのメソッドが複数存在する場合には、org.apache.struts.actions.DispatchActionを使用する場合と同様に、 struts-config.xmlのactionタグにparameter属性の追加と、JSPのサブミットボタンに対し、name属性とvalue属性の2つの属性で、メソッドを指定して下さい。 ~ ***ChangeCaseAction [#c064b57a] [Code] ***struts-config.xml [#m7bd1679] [Code] ***changeCaseInput.jsp [#rb3db819] [Code] HTMLに変換されると以下のようになります。 [Code] ***ProxyActionクラスの使い方 [#r2360f4d] また、ProxyActionクラスを使用して、コンポーネント定義ファイルに記述したActionを呼び出し、処理を委譲する事もできます。これにより、struts-configとコンポーネント定義ファイルに同じクラス名を定義/同期する必要がなくなります。 struts-config内に記述しているactionのpath属性と、コンポーネント定義ファイルに定義したcomponentのname属性が一致している必要があります。 詳細は、「path属性とActionクラスのマッピングについて」を参照してください。 ~ また、ProxyActionクラスのみに関しては、struts-configに、S2用のRequestProcessorを登録しなくとも、S2と連動する事ができます。ただし、他のActionクラスもS2と連動させたい場合には、前述のように、S2用のRequestProcessorをstruts-config.xmlに登録する必要があります。これは、特定のActionクラスのみを、S2と連動する為に有効である事を意味します。 ~ ***struts-config.xml [#y5125b34] [Code] ***Subtract.dicon [#efc847e7] [Code] ***struts-config内に記述しているactionの、type属性を記述せずにActionクラスを指定する [#ie202fc6] ProxyActionクラスの使い方と同様に、struts-config内に記述しているactionのpath属性と、コンポーネント定義ファイルに定義したcomponentのname属性を一致させる事によりtype属性を記述せずにActionクラスを呼び出す事が出来ます。詳細は、「path属性とActionクラスのマッピングについて」を参照してください。この手法を利用する為には条件があります。それは、type属性、forward属性、include属性の3つの属性が無い事です。これにより、struts-configとコンポーネント定義ファイルに同じクラス名を定義/同期する必要がなくなります。 ~ ***struts-config.xml [#m7af3510] [Code] ***Divide.dicon [#ca1d99df] [Code] ***path属性とActionクラスのマッピングについて [#h3c86bf7] ここでは、前述の「ProxyActionクラスの使い方」と、 「struts-config内に記述しているactionの、type属性を記述せずにActionクラスを指定する」で行った、 path属性とActionクラスのマッピングについての、詳細情報を記述します。 ~ 以下の、web.xml、struts-config、そして、コンポーネント定義ファイルが存在するとします。 ~ ***web.xml [#fd8b9b8e] [Code] ***struts-config.xml [#l57388b4] [Code] ***struts-config-foo.xml [#r1f142ea] [Code] ***コンポーネント定義ファイル [#o781e2e9] [Code] デフォルトのモジュール(struts-config.xmlで動作するモジュール)であれば、struts-config内に記述しているactionタグのpath属性と、コンポーネント定義ファイル内に記述しているcomponentタグのname属性でマッピングを行います。下記のサブモジュールの(2)のパターンになります。~ サブモジュール(この例では、struts-config-foo.xmlで動作するモジュール)であれば、マッピング方法が2つ存在します。~ (1)モジュール(prefix)名(/foo)+path属性(/baz)=name属性(/foo/baz)~ (2)path属性(/baz)=name属性(/baz) ~ コンポーネントを取得する優先順位は、(1)、(2)の順になります。つまり、名前が/foo/bazであるコンポーネントが見つからなければ、名前が/bazであるコンポーネントを取得します。 ~ また、org.seasar.struts.ComponentNameCreatorをimplementsしたクラスを作成し、app.diconから登録する事で、上記のデフォルトのマッピング方法を替える事が出来ます。~ ***適用へのヒント [#ce1aaf1a] サポートする機能~ :(1)自動的なDIのサポート セッター・インジェクション、 コンストラクタ・インジェクションを利用しての、 Actionクラスへのサービスクラスなどの自動的なDIが可能な場合 :(2)インスタンス変数を使いたい場合 コンポーネントのinstance属性をprototypeとして、Actionクラスのインスタンス変数を使いたい場合 :(3)AOPを適用したい場合 Actionから、DAOを直接利用した場面で、Actionのメソッドにトランザクションをかけたい場合など :(4)明示的な、DIが必要な場合 メソッド・インジェクションを利用したい場合や、 セッター・インジェクション/コンストラクタ・インジェクションにてコンテナによる自動的なDIが出来ない場合 [Chart] メリット・デメリット~ [Chart] 特に理由のない場合は、POJOActionもしくは、Addの例を使用する事を推奨します。 ~ ***RequestProcessorをコンポーネントから取得する [#xb5ce434] Actionクラスに共通のアスペクトを適用するのと同様の事が、RequestProcessorをコンポーネントから取得することによって可能になります。また、アスペクトの適用以外にも他のコンポーネントと同様の使い方もすることが出来ます。 ~ まず、S2ActionServletをweb.xmlに登録する必要があります。 web.xmlに記述するサーブレットをorg.apache.struts.action.ActionServletではなく、 org.seasar.struts.S2ActionServletもしくは、org.seasar.struts.S2RedeployableActionServletと記述してください。(S2ActionServletは、ActionServletを継承、S2RedeployableActionServletは、RedeployableActionServletを継承したサーブレットとなっています。) ~ また、org.apache.struts.action.ActionServletではなく、上記2つのサーブレットを使用する場合は、struts-config.xmlにRegistActionClassPlugInを登録する必要はありません。 ~ ***web.xml [#d1899aa5] [Code] 今回の例では、S2RequestProcessorにMeasureTimeInterceptorというアスペクトを適用することで、各リクエストの処理時間を測定し標準出力しています。 ~ ***RequestProcessor.dicon [#j06c05b9] [Code] ***タグライブラリについて [#d278e91c] S2Strutsでは、ButtonTagとSubmitTagを用意しています。どちらも、Strutsのタグを拡張した形となっています。 ~ ButtonTag~ http://struts.apache.org/userGuide/struts-html.html#button ~ に加えて、追加になった属性は、以下です。 [Chart] SubmitTag~ http://struts.apache.org/userGuide/struts-html.html#submit ~ に加えて、追加になった属性は、以下です。 [Chart] *英文 [#d95adfcd] **Overview of S2Struts [#l1046444] **S2Struts reference [#h298d128] ***Operating environment and Eclipse project setup [#k28cf86f] ***Basic Usage [#j78cde8f] ***Usage POJO as Action [#s2d1a3db] ***Usage of ProxyAction classes [#df1a3947] ***Indicating Action classes without type attribute of action in struts-config [#u3d136a1] ***About the mapping of Path attributes and Action classes [#v34a3cdb] ***Hints on usage [#a7d6d996] ***Acquire a RequestProcessor from a component [#oa393fdd] ***About Tag library [#ff72cf03] #comment(below) -とりあえず5月中に草稿を上げる予定で、タイトルだけ上げました。s2StrutsUnitが先に終わっていつまで経ってもメインの方が上がらないというのも(^^;なので、頑張ります。 -- [[Terada]] &new{2005-04-17 03:17:40 (日)}; #comment