web server apache tomcat11-08-JNDI Resources

老马啸西风發表於2024-04-19

前言

整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。

開源專案

從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。

系列文章

web server apache tomcat11-01-官方文件入門介紹

web server apache tomcat11-02-setup 啟動

web server apache tomcat11-03-deploy 如何部署

web server apache tomcat11-04-manager 如何管理?

web server apache tomcat11-06-Host Manager App -- Text Interface

web server apache tomcat11-07-Realm Configuration

web server apache tomcat11-08-JNDI Resources

web server apache tomcat11-09-JNDI Datasource

web server apache tomcat11-10-Class Loader

...

介紹

Tomcat為每個在其下執行的Web應用程式提供了一個JNDI InitialContext實現例項,以與Jakarta EE應用程式伺服器提供的例項相容。Jakarta EE標準在/WEB-INF/web.xml檔案中提供了一組標準元素,用於引用/定義資源。

有關JNDI的程式設計API和Jakarta EE伺服器支援的功能的更多資訊,請參見以下規範,Tomcat模擬了它提供的服務:

  • Java命名和目錄介面(從JDK 1.4開始包含)

  • Jakarta EE平臺規範(特別是,請參見命名章節)
    web.xml配置
    以下元素可用於Web應用程式部署描述符(/WEB-INF/web.xml)中,以定義資源:

  • <env-entry> - 環境條目,一個單值引數,可用於配置應用程式的操作方式。

  • <resource-ref> - 資源引用,通常是指用於資源的物件工廠,例如JDBC DataSource、Jakarta Mail Session或配置到Tomcat中的自定義物件工廠。

  • <resource-env-ref> - 資源環境引用,Servlet 2.4中新增的一種資源引用變體,用於簡化對不需要身份驗證資訊的資源的配置。
    只要Tomcat能夠識別一個適當的資源工廠來建立資源,並且不需要進一步的配置資訊,Tomcat就會使用/WEB-INF/web.xml中的資訊來建立資源。

Tomcat提供了一些針對JNDI資源的特定於Tomcat的選項,這些選項無法在web.xml中指定。這些選項包括closeMethod,它可以在Web應用程式停止時更快地清理JNDI資源,以及singleton,它控制是否為每個JNDI查詢建立資源的新例項。要使用這些配置選項,資源必須在Web應用程式的<Context>元素或$CATALINA_BASE/conf/server.xml中的<GlobalNamingResources>元素中指定。

context.xml配置
如果Tomcat無法識別適當的資源工廠和/或需要額外的配置資訊,則必須在Tomcat能夠建立資源之前指定額外的Tomcat特定配置。Tomcat特定的資源配置輸入在<Context>元素中,該元素可以在$CATALINA_BASE/conf/server.xml或最好是每個Web應用程式的上下文XML檔案(META-INF/context.xml)中指定。

使用以下元素在<Context>元素中執行Tomcat特定的資源配置:

  • <Environment> - 配置標量環境條目的名稱和值,這些環境條目將透過JNDI InitialContext公開給Web應用程式(相當於在Web應用程式部署描述符中包含<env-entry>元素)。
  • <Resource> - 配置資源的名稱和資料型別,該資源可供應用程式使用(相當於在Web應用程式部署描述符中包含<resource-ref>元素)。
  • <ResourceLink> - 向全域性JNDI上下文中定義的資源新增連結。使用資源連結使Web應用程式可以訪問在<Server>元素的<GlobalNamingResources>子元素中定義的資源。
  • <Transaction> - 新增用於例項化可在java:comp/UserTransaction處可用的UserTransaction物件例項的資源工廠。
    可以將任意數量的這些元素巢狀在一個<Context>元素內,並且只與該特定Web應用程式相關聯。

如果在<Context>元素中定義了資源,那麼不需要在/WEB-INF/web.xml中定義該資源。但是,建議在/WEB-INF/web.xml中保留條目,以記錄Web應用程式的資源需求。

如果對於在Web應用程式部署描述符(/WEB-INF/web.xml)中包含的<env-entry>元素和在Web應用程式的<Context>元素的一部分中的<Environment>元素都定義了相同的資源名稱,則僅當相應的<Environment>元素允許時(透過將override屬性設定為“true”),部署描述符中的值將優先。

全域性配置
Tomcat維護伺服器的全域性資源的單獨名稱空間。這些在$CATALINA_BASE/conf/server.xml<GlobalNamingResources>元素中配置。您可以透過使用<ResourceLink>將這些資源暴露給Web應用程式,以將其包含在每個Web應用程式的上下文中。

如果使用<ResourceLink>定義了資源,那麼不需要在/WEB-INF/web.xml中定義該資源。但是,建議在/WEB-INF/web.xml中保留條目,以記錄Web應用程式的資源需求。

使用資源
在Web應用程式最初部署時,InitialContext被配置,並且被提供給Web應用程式元件(用於只讀訪問)。所有配置的條目和資源都放置在JNDI名稱空間的java:comp/env部分中,因此對於資源的典型訪問 - 在本例中是對JDBC DataSource的訪問 - 看起來像這樣:

// 獲取我們的環境命名上下文
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");

// 查詢我們的資料來源
DataSource ds = (DataSource)
  envCtx.lookup("jdbc/EmployeeDB");

// 從池中分配並使用連線
Connection conn = ds.getConnection();
... 使用此連線訪問資料庫 ...
conn.close();

Tomcat標準資源工廠
Tomcat包含一系列標準資源工廠,可以為您的Web應用程式提供服務,並透過元素提供配置靈活性,而無需修改Web應用程式或部署描述符。以下各小節詳細介紹了標準資源工廠的配置和用法。

有關如何建立、安裝、配置和使用自定義資源工廠類的資訊,請參閱新增自定義資源工廠。

注意 - 在標準資源工廠中,只有“JDBC資料來源”和“使用者事務”工廠被要求在其他平臺上可用,並且只有在平臺實現了Jakarta EE規範時才需要。所有其他標準資源工廠以及您自己編寫的自定義資源工廠都特定於Tomcat,並且不能假定它們在其他容器上可用。

通用JavaBean資源
0. 介紹
此資源工廠可用於建立符合標準JavaBeans命名約定的任何Java類的物件(即具有零引數建構函式,並且具有符合setFoo()命名模式的屬性設定器)。如果工廠的singleton屬性設定為false,則該資源工廠僅在每次查詢此條目時建立適當的bean類的新例項。

使用此設施的步驟如下所述。

  1. 建立您的JavaBean類
    建立每次資源工廠被查詢時將例項化的JavaBean類。例如,假設您建立了一個名為com.mycompany.MyBean的類,其程式碼如下所示:
package com.mycompany;

public class MyBean {

  private String foo = "Default Foo";

  public String getFoo() {
    return (this.foo);
  }

  public void setFoo(String foo) {
    this.foo = foo;
  }

  private int bar = 0;

  public int getBar() {
    return (this.bar);
  }

  public void setBar(int bar) {
    this.bar = bar;
  }
}
  1. 宣告您的資源需求
    然後,修改您的Web應用程式部署描述符(/WEB-INF/web.xml)以宣告您將請求此bean的新例項的JNDI名稱。最簡單的方法是使用元素,例如:
<resource-env-ref>
  <description>
    MyBean例項的物件工廠。
  </description>
  <resource-env-ref-name>
    bean/MyBeanFactory
  </resource-env-ref-name>
  <resource-env-ref-type>
    com.mycompany.MyBean
  </resource-env-ref-type>
</resource-env-ref>

警告 - 請確保您遵循Web應用程式部署描述符的DTD所要求的元素順序!有關詳細資訊,請參閱Servlet規範。

  1. 編寫您的應用程式對此資源的使用
    對此資源環境引用的典型用法可能如下所示:
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
MyBean bean = (MyBean) envCtx.lookup("bean/MyBeanFactory");

writer.println("foo = " + bean.getFoo() + ", bar = " +
               bean.getBar());
  1. 配置Tomcat的資源工廠
    要配置Tomcat的資源工廠,請向此Web應用程式的元素新增如下所示的元素。
<Context ...>
  ...
  <Resource name="bean/MyBeanFactory" auth="Container"
            type="com.mycompany.MyBean"
            factory="org.apache.naming.factory.BeanFactory"
            bar="23"/>
  ...
</Context>

請注意,資源名稱(在這裡是bean/MyBeanFactory)必須與Web應用程式部署描述符中指定的值匹配。我們還初始化了bar屬性的值,這將導致在返回新bean之前呼叫setBar(23)。因為我們沒有初始化foo屬性(雖然我們可以),所以bean將包含由其建構函式設定的任何預設值。

如果bean屬性的型別為String,則BeanFactory將使用提供的屬性值呼叫屬性設定器。如果bean屬性型別為原始型別或原始包裝型別,則BeanFactory將將該值轉換為適當的原始型別或原始包裝型別,然後在呼叫setter時使用該值。某些bean具有無法從String自動轉換的型別的屬性。如果bean提供了一個具有相同名稱但接受String的備用setter,則BeanFactory將嘗試使用該setter。如果BeanFactory無法使用值或執行適當的轉換,則設定屬性將失敗,並顯示命名異常。

較早的Tomcat版本中可用的forceString屬性已被刪除,作為加強安全措施。

相關文章