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 になるはずなので,自動登録じゃないのかな,と.
id:koichikさんのコメント
dicon に定義してるとすると,デフォルトは singleton なので,.interceptor パッケージにあれば自動登録されます.
やばい。そうなのか、そういうことなのか。ええかええか、ええのんか。
ということで自動登録にすることにしました。
以下、修正点
- 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になっている?
何かがおかしい。