以前は、JSF 2 アプリの Cookie に基づく Open Session In Conversation フィルターを使用していました。今、私は同じメカニズムを構築したいと考えていますが、テクノロジーに依存しません。いくつかのコードを再利用して、これをOncePerRequestFilterを拡張するクラスに記述しました。
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
UUID conversationId = lookupConversationOrCreateIfNecessary(request,
response);
log.debug("Binding conversation '{}' to request '{}'", conversationId,
request);
bindConversation(conversationId, request);
try {
filterChain.doFilter(request, response);
} finally {
log.debug("Unbinding conversation '{}' from request '{}'",
conversationId, request);
unbindConversation(conversationId, request);
}
}
今、到達したら、 Hibernate SessionbindConversation(conversationId, request)
にマップされている conversationId を指す request 属性を追加するだけです。
とにかく、JSF では、これを使用してCurrentSessionContextFacesContext.getCurrentInstance().getExternalContext().getRequest()
を使用して実装することで、現在のリクエストにアクセスできます。しかし、単純なサーブレットでは、現在のリクエストにプログラムでアクセスするにはどうすればよいでしょうか?
注: 私は OncePerRequestFilter javadocs を読んでいて、これを見つけました:
Servlet 3.0 では、別のスレッドで発生する REQUEST または ASYNC ディスパッチの一部としてフィルタを呼び出すことができます。フィルターは、非同期ディスパッチに関与する必要があるかどうかを web.xml で構成できます。ただし、場合によっては、サーブレット コンテナーが異なるデフォルト構成を前提とします。したがって、サブクラスは、メソッド shouldNotFilterAsyncDispatch() をオーバーライドして、スレッドの初期化、ロギング、セキュリティなどを提供するために両方のタイプのディスパッチ中に [sic] 実際に 1 回呼び出す必要がある場合、静的に宣言できます。このメカニズムは、web.xml でフィルターをディスパッチャー タイプで構成する必要性を補完し、置き換えるものではありません。
では、 ThreadLocalを使用して目的を達成するのは危険でしょうか?