我曾經有一個基於Cookie的JSF 2應用程序中的對話中的開放會話。現在我想建立相同的機制,但技術不可知論者。重用一些代碼,我一直在擴展OncePerRequestFilter類寫成這樣:訪問任何地方的HttpServletRequest
@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);
}
}
現在,當我到達bindConversation(conversationId, request)
我只是添加指向被映射到一個Hibernate Session中的conversationId請求屬性。
總之,在JSF中,我可以通過使用FacesContext.getCurrentInstance().getExternalContext().getRequest()
來訪問當前的請求,並使用這個來實現CurrentSessionContext。但在普通的servlet中,我如何以編程方式訪問當前請求?
注:我已讀OncePerRequestFilter javadocs中,我發現這一點:
作爲Servlet的3.0的,過濾器可以被調用作爲請求或發生在單獨的線程 ASYNC調度的一部分。在web.xml中配置的過濾器可以是 ,它是否應該參與異步 調度。但是,在某些情況下,servlet容器會採用不同的 默認配置。因此,子類可以重寫方法 shouldNotFilterAsyncDispatch()靜態聲明,如果它們確實被調用,那麼在這兩種類型的調度期間,爲了 提供了線程初始化,日誌記錄,安全等等。此 機制補充並且不取代在web.xml中使用調度程序類型配置 過濾器的需要。
那麼,使用ThreadLocal來達到我想要的效果會很危險嗎?
ThreadLocal是JSF使用的,因此不應該是危險的。 JSF可以做它做的事情,因爲所有事情都是通過儀器可能發生的單一FacesServlet進行路由。如果你想做類似的事情,你必須使用類似的策略。 – Gimby
是的,但是如果過濾器配置了ASYNC分派,許多線程將使用該機制。除非這些線程是從運行bindConversation代碼的線程派生的,否則我將得到NullPointerExceptions。不是嗎?此外,清理會很棘手,因爲如果我將請求放入InheritableThreadLocal中,容器可能會使用一個池並導致問題? – ElderMael