前の記事にて、4つの連携方法をみました。
その中では、DelegatingActionProxyを使用する方法が良さそうという結論を出しました。
それでも、以下の弱点があることも書きました。
1.Strutsのactionに設定するpathと同じidでSpring設定ファイルにActionクラスを設定しないといけません。
ですので、1つパスが増えると2つのファイルに記述をしないといけないという問題があります。
2.Springであれば、beanの使い回しができるのが当たり前ですが、beanのidをパス名と合わせない
といけないです。ですので、同じActionクラスでも、path名が違えば、違うbeanとして設定しないといけません。
3.もうひとつ、beanのid名を自由に選べないという弱点もあります。
1を解決することはできませんが、2と3は解決できます。
その方法を見てみましょう。
一つ断っておくと、これは自分独自のやり方です。
Springなどでスタンダードなやり方は前の記事の4つのうちのどれかです。
でも、たぶん問題ないかとは思いますが、参考にするのは自己責任でお願いします。
【新たなProxyの作成】
以下のクラスを作ります。
StrutsのコンフィグファイルからBean名を取得するように変更しています。
import org.apache.commons.validator.GenericValidator; import org.apache.struts.action.ActionMapping; import org.springframework.beans.FatalBeanException; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.struts.DelegatingActionProxy;
public class MyProxy extends DelegatingActionProxy { /** * actionタグのproertyタグ、parameter属性の値を順番に取得し、nullでない方をbean名として返す。 */ protected String determineActionBeanName(ActionMapping mapping) { //bean名の取得(propertyから) String beanName = mapping.getProperty("spring-bean"); if(!GenericValidator.isBlankOrNull(beanName)){ return beanName; } //propertyで見つからないとき、パラメターからbean名を取得 beanName = mapping.getParameter(); if(!GenericValidator.isBlankOrNull(beanName)){ return beanName; } //どちらからも見つからない場合 throw new FatalBeanException("struts-config error, " + "should set 'spring-bean' property or 'parameter' attibute."); } }
【Strutsファイルの設定】
Strutsのファイルには以下のようにset-propertyでSpringのbeanのidを設定する。
ここではtestActionというbeanを設定しています。
<action path="/test" type="MyProxy" scope="request" >
<set-property key="spring-bean" value="testAction"/>
</action>
【Springファイルの設定】
Springのファイルには以下のように、普通にbeanの設定をします。
<bean id="testAction" class="presentation.action.TestAction" />
もしくは、以下のようにスキャンを使って指定のパッケージ配下のクラスを自動でDIします。
この場合、bean名はクラス名の先頭を小文字にしたものになります。
これなら楽ですね
<context:include-filter type="regex" expression=".*Action"/>
</context:component-scan>
※もちろんAction内のプロパティのDIは、@AutoWiredか@Resourceを使用します。
【説明】
Strutsのactionタグのパス名とSpringのbean名が違うことが分かるでしょうか?
変わりに、actionのtype属性には先ほど作成したMyProxyを設定しています。
Springが提供するDelegatingActionProxy クラスは、機能拡張しやすいように機能をこまめにメソッドにしています。
determineActionBeanNameメソッドは、こまめに変更できるようにしたメソッドの一つで、Strutsに設定したパス名をmappingから取得し返却する役割を持っています。
このメソッドの呼び出し元では、返却されたパス名と同名のbeanをSpringのApplicationContextから取得する処理を行っています。
ですので、このメソッドを変更するだけで目的を達成できます!
これだけです。
でも、これにより、さまざまなことができます。
それは応用例で!
他にも機能を変更したい場合、DelegatingActionProxy クラスのソースを見てみましょう。
たいていの場合、やりたいことをオーバーライドするだけでできると思います。
【応用例】
例えば、MyProxyをさらに拡張してAという機能をつけたとしましょう。
そして、Strutsの設定ファイルに以下のように記述します
<action path="/extest" type="MyProxyA" scope="request" >
<set-property key="spring-bean" value="testAction"/>
</action>
すると、Springのbeanの設定の変更無くパスを追加できて、
しかもAという機能が付いた画面を提供できます。
再利用性が高まったでしょ?
参考: