3

別の質問に対するこの回答の無関係な部分を見ると、質問の例でリクエストとレスポンスへの参照がスレッドセーフでない理由は理解できますが、SessionScoped Bean がバインドされている HttpSession を参照することがスレッドセーフでないのはなぜですか?

@SessionScoped
public class SessionManager {
    HttpSession session = null;
    ...
    @PostConstruct void initialize() {
        this.session = (HttpSession)FacesContext.getCurrentInstance().getExternalContext().getSession(false);
    }

    private void onLogin(@Observes @LoggedIn User user) {

        // (1) housekeeping stuff

        // (2) destroy older, duplicate login session, if user did not previously 
        //     logout, in which case it would be really handy to have a reference
        //     to HttpSession. 

    }
}
4

1 に答える 1

2

上記でスケッチした例 (OP を参照) を実装しているときに、セッションへの参照を維持することは実際にはスレッドセーフではないため、適切ではないことに気付きました。臭いコードです。

古いセッションが無効になっただけでなく、現在のセッションもコンテナーによって破棄されていることに驚きました。そのため、ユーザーは両方のブラウザーでログアウトされました。後で、Websphere のベスト プラクティス ドキュメントに出会いました。私は Websphere を使用していませんが、セッションをキャッシュすることはまったく良い方法ではないことを理解するのに役立ちました。

各サーブレットまたは JSP ファイルの外部で HttpSession オブジェクトを保存して再利用しようとしないでください。

HttpSession オブジェクトは HttpRequest の関数であり (これは req.getSession メソッドを介してのみ取得できます)、そのコピーはサーブレットまたは JSP ファイルのサービス メソッドの存続期間中のみ有効です。HttpSession オブジェクトをキャッシュして、サーブレットまたは JSP ファイルの範囲外で参照することはできません。

HttpSession をキャッシュする必要はありません。Set<String> invalidatedLoginSessionIds.代わりにセッション ID をキャッシュし、重複セッションが発見されたら、単純に以前の重複セッションの ID を. そのようなリクエストが受信されない場合、古いセッションは単にタイムアウトして破棄されるため、心配する必要はありません。

于 2013-01-29T19:07:33.220 に答える