簡體   English   中英

如何從Java類(而非Servlet)獲取ServletContext屬性

[英]How to get ServletContext attribute from a java class (not servlet)

晚上好! 我有一個帶登錄注銷功能的Web應用程序,您可以在其中購買或出售一些產品。 我的查詢存儲在一個名為DBManager的Java類中,該類只有從Servlet調用的靜態方法(我不能使用JSP,因為在這個項目中我們不能使用它們,教授給了我們這個約束)。

所以這是問題所在:我曾經用ServletContextListener管理連接。 contextInitialized我建立了連接,而在contextDestroyed我關閉了它。 使用ServletContext.setAttribute(Connection)存儲屬性“ Connection”。

如何通過java類(而非servlet) DBManager獲取此參數? 我必須在servlet內使用getServletContext()獲取對象,然后將其作為屬性傳遞,否則有避免這種情況的捷徑?

在方法contextInitialized中打開連接並在contextDestroyed中關閉它是一個不好的解決方案。 想象一下,您的網站同時有兩個訪問者。 他們現在將共享相同的數據庫連接。 如果使用事務,最終將導致意外結果,其中一個訪問者提交另一訪問者執行的事務的中間狀態。 而且,如果連接丟失(可能是由於重新啟動了數據庫服務器),則您的應用程序將失敗,因為它不會重新建立連接(除非您擁有非常聰明的JDBC驅動程序)。

一個非常昂貴但安全的解決方案是為每個數據庫操作打開一個新連接,並在操作后立即將其再次關閉。

對於一個完美的解決方案,您將使用某種連接池。 每當需要執行數據庫語句(或語句序列)時,都可以從池中借用連接。 完成后,您將把連接返回到池中。 大多數池實現都執行諸如驗證(檢查連接是否仍處於“活動”狀態)之類的事情,並且多個線程(不同訪問者同時發送的不同HTTP請求)可以並行執行語句。

如果您想使用此解決方案,也許Commons DbUtils庫適合您: http ://commons.apache.org/dbutils/

或者,您可以查看Java應用程序服務器或Servlet引擎(Tomcat?)的文檔,以了解其提供的內置DB連接池功能。

您可以更改類以接收連接,而不必隨意獲取連接。 這樣,您就可以傳遞任何連接實例(如果需要從另一個數據庫獲取數據會發生什么情況?)。

另外,假設代碼將被移植到桌面。 通過這種方法,您可以重復使用DAO,而無需進行任何更改。

class DBManager {
  private Connection connection;

  public DBManager(Connection connection) {
    this.connection = connection;
  }
  //methods that will use the connection
}

HttpServlet doPostdoGet方法中,可以調用getServletContext()

ServletContext sc = getServletContext();
DataSource ds = (DataSource) sc.getAttribute("ds");
Connection conn = ds.getConnection();

Servlet可以按名稱將對象屬性綁定到上下文中。 綁定到上下文中的任何屬性都可用於屬於同一Web應用程序的任何其他servlet。

上下文屬性對於創建它們的JVM是本地的。 這樣可以防止ServletContext屬性成為分布式容器中的共享內存存儲。 當需要在分布式環境中運行的servlet之間共享信息時,應將這些信息放入會話中,存儲在數據庫中或在Enterprise JavaBeans組件中設置。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM