前の記事にて、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:component-scan base-package="presentation.action" annotation-config="false">
<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という機能が付いた画面を提供できます。
再利用性が高まったでしょ?
参考:
Strutsと連携するには?(理論編)
Strutsと連携するには?(実践編)