S2Strutsを使うと、S2とStrutsが簡単に連動するようになります。 Actionクラスにサービスコンポーネントが自動的に設定されるので、 Actionクラスの役割は適切なサービスコンポーネントを呼び出すだけになります。 Actionクラスはコントローラに徹することで、プレゼンテーション層とサービス層の役割分担も明確になります。また、Actionに対してAOPを適用することもできます。
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/にアクセスすると四則演算のサンプルを見ることができます。
まず、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を登録して下さい。
[Code]
次に、S2とStrutsを連動させるために、S2用のRequestProcessorをstruts-config.xmlに登録する必要があります。 S2RequestProcessorとS2TilesRequestProcessorを用意しています。これらは、それぞれ、Strutsの、RequestProcessorとTilesRequestProcessorに相当します。
[Code]
上記のRequestProcessorから生成される全てのActionクラスがS2と連動するようになります。 RegistActionClassPlugInを登録する事により、S2と連動するActionを、明示的にコンポーネント定義に登録しておく必要はありません(Add.dicon)。インターフェースに対するセッターメソッドを定義しておけば、自動的にセッター・インジェクションが行われます。また、インターフェースのみが引数の、コンストラクタを定義している場合は、自動的に、コンストラクタ・インジェクションが行われます。
[Code]
ただし、Actionに対して、AOPの適用や、 メソッド・インジェクションを行いたい場合、また、コンポーネントの依存関係が、型によって自動的に解決されない場合などには、他のコンポーネントと同様に、コンポーネント定義にActionクラスを登録しておく必要があります(Multiply.dicon)。
[Code]
インスタンス属性は、任意です。このコンポーネント定義ファイルでは、では、他の演算サンプルとの比較のために、prototypeを指定しています。 singletonとするのであれば、明示的な指定の必要はありません。instance属性に、prototypeを指定をしていすると、 Actionクラスを、実装する時に、インスタンスフィールドを使用できるという利点があります。
また、これらの定義ファイルは、アプリケーション全体の定義であるapp.diconに登録する必要があります。
[Code]
サービスコンポーネントを受け取るためにActionクラスはコンストラクタもしくはセッターメソッドを定義しておきます。 execute()メソッドでは、サービスに処理を委譲するのみとなるので、非常にすっきりしたコードになっていることが分かると思います。
[Code]
org.apache.struts.action.Actionを継承しないPOJOをActionとして使用する事が出来ます。
以下のように、インターフェースと、実装クラスを作成し実装クラスは、コンポーネント定義ファイルに定義して下さい。アクションメソッドの戻り値は、Stringとして、forward名を返すようにして下さい。そして、struts-configには、インターフェースをactionタグのtype属性に指定して下さい。
[Code]
[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クラスに記述する必要があります。
[Code]
[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つの属性で、メソッドを指定して下さい。
[Code]
[Code]
[Code]
HTMLに変換されると以下のようになります。
[Code]
また、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と連動する為に有効である事を意味します。
[Code]
[Code]
ProxyActionクラスの使い方と同様に、struts-config内に記述しているactionのpath属性と、コンポーネント定義ファイルに定義したcomponentのname属性を一致させる事によりtype属性を記述せずにActionクラスを呼び出す事が出来ます。詳細は、「path属性とActionクラスのマッピングについて」を参照してください。この手法を利用する為には条件があります。それは、type属性、forward属性、include属性の3つの属性が無い事です。これにより、struts-configとコンポーネント定義ファイルに同じクラス名を定義/同期する必要がなくなります。
[Code]
[Code]
ここでは、前述の「ProxyActionクラスの使い方」と、 「struts-config内に記述しているactionの、type属性を記述せずにActionクラスを指定する」で行った、 path属性とActionクラスのマッピングについての、詳細情報を記述します。
以下の、web.xml、struts-config、そして、コンポーネント定義ファイルが存在するとします。
[Code]
[Code]
[Code]
[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から登録する事で、上記のデフォルトのマッピング方法を替える事が出来ます。
サポートする機能
:(1)自動的なDIのサポート セッター・インジェクション、 コンストラクタ・インジェクションを利用しての、 Actionクラスへのサービスクラスなどの自動的なDIが可能な場合
:(2)インスタンス変数を使いたい場合 コンポーネントのinstance属性をprototypeとして、Actionクラスのインスタンス変数を使いたい場合
:(3)AOPを適用したい場合 Actionから、DAOを直接利用した場面で、Actionのメソッドにトランザクションをかけたい場合など
:(4)明示的な、DIが必要な場合 メソッド・インジェクションを利用したい場合や、 セッター・インジェクション/コンストラクタ・インジェクションにてコンテナによる自動的なDIが出来ない場合
[Chart]
メリット・デメリット
[Chart]
特に理由のない場合は、POJOActionもしくは、Addの例を使用する事を推奨します。
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を登録する必要はありません。
[Code]
今回の例では、S2RequestProcessorにMeasureTimeInterceptorというアスペクトを適用することで、各リクエストの処理時間を測定し標準出力しています。
[Code]
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]