我有一種方法,沒有得到任何可用於獲取實際的servlet上下文的方法。實際上,它就像如何在沒有任何請求,會話等情況下獲取上下文?
public String getSomething() { ... }
但是爲了計算結果,我需要實際的線程特定的servlet結構。
我認爲,在應用程序上下文中的某處深處,應該存在一些像特定於線程的存儲,這可以通過調用某些系統類的靜態方法來實現。
我在tomcat6 servlet容器中,但如果需要的話,Spring也可用。
我有一種方法,沒有得到任何可用於獲取實際的servlet上下文的方法。實際上,它就像如何在沒有任何請求,會話等情況下獲取上下文?
public String getSomething() { ... }
但是爲了計算結果,我需要實際的線程特定的servlet結構。
我認爲,在應用程序上下文中的某處深處,應該存在一些像特定於線程的存儲,這可以通過調用某些系統類的靜態方法來實現。
我在tomcat6 servlet容器中,但如果需要的話,Spring也可用。
一個明顯的解決方案是將上下文作爲參數傳遞,因爲您顯然正在運行上下文通常可用的代碼。
如果由於某種原因,您認爲這不是您可以做的事情(我希望聽到原因),另一種方法是創建一個servlet過濾器,然後創建例如ThreadLocal<ServletContext>
。
將ServletContextListener
加入您的web.xml
。這將在您的webapp加載時調用。在contextInitialized()
方法中,您可以將ServletContext
存儲在一個靜態變量中,以備後用。然後,你就可以訪問ServletContext
以靜態方式:
class MyListener implements ServletContextListener {
public static ServletContext context;
@Override
public void contextInitialized(ServletContextEvent sce) {
context = sce.getServletContext();
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
context = null;
}
}
將它添加到web-xml
這樣的:
<web-app>
<listener>
<listener-class>
com.something.MyListener
</listener-class>
</listener>
</web-app>
而且你可以從任何地方像這樣訪問:
public String getSomething() {
// Here you have the context:
ServletContext c = MyListener.context;
}
備註:
您可能希望將其存儲爲private
,並提供getter
方法,並在使用它之前檢查值爲null
。
可以自動裝配的servlet上下文中
@Autowired
ServletContext servletContext;
給出如果沒有指向一些有用的東西,我知道的唯一辦法是在包含當前的ServletContext一類的靜態屬性。這是微不足道的一個ServletContextListener
:
@WebListener
public class ServletContextHolder implements ServletContextListener {
private static ServletContext servletContext;
public static ServletContext getServletContext() {
return servletContext;
}
@Override
public void contextInitialized(ServletContextEvent sce) {
servletContext = sce.getServletContext();
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
servletContext = null;
}
}
然後從任何地方使用
ServletContextHolder.getServletContext();
如果你使用Spring,你還可以使用RequestContextHolder
從那裏得到任何東西訪問當前請求(你需要)
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
.getRequestAttributes()).getRequest();
當然,如果作品servlet應用這種方式,而不是在門戶的 - 你將不得不使用PortletRequestAttributes和finaly獲取端口letRequest
真的需要'ThreadLocal'嗎?AFAIK,'ServletContext'每個虛擬機只定義一次 – epoch 2014-10-31 09:03:46
@epoch也許不同的web應用有不同的ServletContext? – peterh 2014-10-31 09:19:47
非常感謝你 - 終於我完成了你的第一個想法:我將一個新的setter中的servletContext給了bean。也許這不是最節能的解決方案,但它肯定是最簡單和最獨立於平臺的。 – peterh 2014-10-31 09:21:18