minimize

事業拡大のため、新しい仲間を募集しています。
→詳しくはこちら

ここでは、Struts2 に関する小ネタを書いていきます。
新しい記事が上です。

VelocityManager を取得する方法

Struts2 では、全ての基本が Action になっています。
この概念は XWork2 というフレームワークによって実装されていて
これが Struts2 の大枠になります。

Actionで VelocityManager を取得するのは、非常に簡単です。

public class XXAction {
    
    /** VelocityManager */
    private VelocityManager velocityManager;
    
    @Inject
    public void setVelocityManager(VelocityManager mgr) {
        this.velocityManager = mgr;
    }
    
}

このように、@Inject を使います。
これも XWork の機能で、こうやって記述しておくと
Action を作成するときにフレームワークが VelocityManager を引数に渡してくれます。
struts-default.xml に以下の記述があります。

<bean class="org.apache.struts2.views.velocity.VelocityManager" name="struts" optional="true" />

これによって、VelocityManager は XWork の Bean として登録されています。

Container の使用

では、Action以外の場所で VelocityManager を取得したい場合はどうするのでしょうか。
あれこれ試した結果、以下のような方法があることがわかりました。

Container container = Dispatcher.getInstance().getContainer();
VelocityManager manager = container.getInstance(VelocityManager.class);

Dispatcher は、Struts2 のクラスです。
これも struts-default.xml に記述されています。

<bean class="org.apache.struts2.dispatcher.Dispatcher" static="true" />

Container は XWork のクラスで、その名の通りBeanのコンテナ管理をしています。
ここに Struts2 で管理している全てのコンテナが登録されているので
あとは自由に使うことができます。

@Inject がうまくいかない場合

余談ですが、@Inject の方式で VelocityManager を取得しようとした場合
たまに null が入っていることがあります。
これはまだ VelocityManager のインスタンスが生成されていないときに
起きる事象で、例えば起動後一発目にアクセスしたときはこの状態です。

VelocityManager が生成、初期化されるのは最初の一回だけなので
二回目以降のアクセスでは問題ないのですが
一回目のアクセス時にはアクションを処理する段階で VelocityManager はまだ空なのです。

こういった場合にも、先ほど紹介した Container を使う方法にすれば
確実に VelocityManager を取得することができます。
container.getInstance() は、Beanが存在しなければ生成(そして初期化)して返し
もし既に存在していればそれをそのまま返します。