Interceptorむずかしい

昨日書いた自作のInterceptorはSAStruts内のクラスであるActionMessagesThrowsInterceptorを参考に、ややシンプルにすることができた。ま、requestの取得だけだけど。

public class UserDtoAutoRetrieveInterceptor extends AbstractInterceptor {

    private static final long serialVersionUID = 1L;
    
    public UserService userService;
    public UserDto userDto;
    
    public Object invoke(MethodInvocation invocation) throws Throwable {
        
        HttpServletRequest request = RequestUtil.getRequest();
        Principal userPrincipal = request.getUserPrincipal();
        
        User user = userService.getUserDto(userPrincipal.getName());
        Beans.copy(user, userDto).execute();
        
        System.out.println("###" + userDto);
        
        return invocation.proceed();
    }

}

しかしUserDtoはActionで宣言しているものとは別物管理となる。UserDtoは@Component(instance = InstanceType.SESSION) と設定しているから、うまくやってくれそうなものなんだけど。

ここはべたべたのsession管理とするか。いい方法がみつかったらそっちにするということで。

Interceptorむずかしい3(解決編)

id:higayasuoさんのご指摘だけでも感謝なのに、id:koichik さんもコメントにてご指摘をくださった。

Interceptor を dicon に登録してますか?

id:koichikさんのコメント

そりゃあしてますよ、もちろん。app.diconに

	<component name="UserDtoAutoRetrieveInterceptor"
        class="kizashi.scheduler.interceptor.UserDtoAutoRetrieveInterceptor"/>

ほらね。*1

SMART deploy で自動登録なら prototype になるはずですが,その場合のコンポーネント名は先頭が小文字の userDtoAutoRetrieveInterceptor になるはずなので,自動登録じゃないのかな,と.
dicon に定義してるとすると,デフォルトは singleton なので,.interceptor パッケージにあれば自動登録されます.

id:koichikさんのコメント

やばい。そうなのか、そういうことなのか。ええかええか、ええのんか。

ということで自動登録にすることにしました。
以下、修正点

  • app.diconに定義した上記定義をコメントアウト、いや、思い切って削除
  • 自作インターセプターのpackageは図らずも.interceptorとしていたので、そのまま。
  • その削除した定義ではnameをUserDtoAutoRetrieveInterceptorとしていたので、addCustomizer で記述したインターセプタのnameをuserDtoAutoRetrieveInterceptorに修正。

修正というか、そもそも余計なことをしていたと・・・。

以下、動作確認
Aさんでログインした場合

Interceptor ###kizashi.scheduler.dto.UserDto@96ac47
Action ###kizashi.scheduler.dto.UserDto@96ac47

Bさんでログインした場合

Interceptor ###kizashi.scheduler.dto.UserDto@1d2052b
Action ###kizashi.scheduler.dto.UserDto@1d2052b

ええやないですか。

というわけでうまくいきました。ご指摘ありがとうございましたm(_ _)m

*1:ここでなんでnameの先頭文字を小文字にしていなかったのだろうかと後悔

Interceptorむずかしい2

ひがさんのご指摘どおり、useLookupAdapter を指定してみた。
customizer.dicon の actionCustomizer に

  <initMethod name="addCustomizer">
    <arg>
      <component class="org.seasar.framework.container.customizer.AspectCustomizer">
        <property name="useLookupAdapter">true</property>
        <property name="interceptorName">"UserDtoAutoRetrieveInterceptor"</property>
        <property name="pointcut">"index"</property>
      </component>
    </arg>
  </initMethod>

と追加した。たぶんこれであってるとおもう。AspectCustomizer にブレークポイントを置いて、フィールドuseLookupAdapterがtrueになっているのも確かめた。

しかし、うまくいかない。
Aさんでアクセスしたとき

Interceptor###kizashi.scheduler.dto.UserDto@16c6da9
Action###kizashi.scheduler.dto.UserDto@1da5d65

もう、この時点で違うインスタンスなのだが、Bさんでアクセスしたら、

Interceptor###kizashi.scheduler.dto.UserDto@16c6da9
Action###kizashi.scheduler.dto.UserDto@fa8ba9

そう。Interceptor側は同じインスタンスをさしている。つまりSingletonになっている?

何かがおかしい。