SAStrutsのインターセプタでセッションを使う

どうも、かつて書いた次の記事に誤りがあるようなので、訂正したいと思う。

SAStrutsでログイン確認インターセプタを使う - idesaku blog
SAStrutsでHttpSessionを使いたい場合、通常はフィールドを一つ定義してやればそこに自動的にバインディングされる。

@Binding
private HttpSession httpSession;

これはActionやServiceでは有効なのだが、インターセプタではこの方法が通用しない。セッションを使って何かするインターセプタを書きたい場合、どうすればよいのか?

かつてSAStrutsでログイン確認インターセプタを使う - idesaku blogを書いた際にこの問題にぶつかり、ネットを調べて回った結果、次のように処理することにした。

HttpSession session =
            (HttpSession) SingletonS2ContainerFactory
                .getContainer()
                .getExternalContext()
                .getSession();

これでうまくいったのだが、どうもHotDeploy時に動作しない場合があるらしい(ClassCastExceptionが投げられる)。この件についてメーリングリストに質問がポストされていた。

[Seasar-user:17184] [SAStruts]インターセプター中での HOT deploy と COOL deploy の違い

これに対する、ひが氏の回答。

Interceptorで、直接セッションを触っているためだと思います。
Map sessionScope =
SingletonS2Container.getComponent("sessionScope");
のようにSeasar2で管理しているオブジェクト経由で
セッションには触るようにしてください。

[Seasar-user:17185] Re: [SAStruts] インターセプター中での HOT deploy と COOL deploy の違い

あー、そう書くのが正しいんですか。なので、前の記事で書いたコードは、次のように書くべきなのだろう。

    private boolean isLoggedIn() {
        Map<String, Object> sessionScope = SingletonS2Container.getComponent("sessionScope");
        
        LoginDto dto = (LoginDto) sessionScope.get("loginDto");
        
        return (loginDto != null && loginDto.id != null);
    }

動作確認していないのだが、たぶん動くだろう。動かなかったらごめん。

それにしても、当該スレッドで提示されているコード、俺が書いたやつとよく似ている…。ありがちな処理だから、誰が書いても似たような外見になるのだろうか。それとも参考にしてくれたのか。そうだったら嬉しいが、同時に変な問題を抱えさせて申し訳ないなぁとも思う。そういうわけで、慌てて訂正した次第。

追記

Seasar 2.4.35で機能追加され、直接HttpSessionを触っても問題無いようになっている。そのため、本記事に合わせてコードを変更するまでもなく、単にバージョンアップさせれば問題は解決する。

しかし、BugではなくImprovementになっているところを見ると、やはり元々はsessionScopeを使って欲しかったのだろうなぁ。