大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

Tomca教程
Tomcat Manager
Tomcat Realm 配置
Tomcat 安全管理
Tomcat JNDI 資源
Tomcat JDBC 數據源
Tomcat 類加載機制
Tomcat JSPs
Tomcat SSL/TLS配置
Tomcat SSI
Tomcat CGI
Tomcat 代理支持
Tomcat MBean 描述符
Tomcat 默認 Servlet
Tomcat 集群
Tomcat 連接器
Tomcat監控與管理
Tomcat 日志機制
Tomcat 基于 APR 的原生庫
Tomcat 虛擬主機
Tomcat 高級 IO 機制
Tomcat 附加組件
Tomcat 安全性注意事項
Tomcat Windows 服務
Tomcat Windows 認證
Tomcat 的 JDBC 連接池
Tomcat WebSocket 支持
Tomcat 重寫機制

Tomcat JNDI 資源

本章概述

Tomcat 為每個在其上運行的 Web 應用都提供了一個 JNDI 的 InitialContext 實現實例,它與Java 企業版應用服務器所提供的對應類完全兼容。Java EE 標準在 /WEB-INF/web.xml 文件中提供了一系列標準元素,用來引用或定義資源。

可通過下列規范了解如何編寫針對 JNDI 的 API 以及 Java 企業版(Java EE)服務器所支持的功能,這也是 Tomcat 針對其所提供的服務而仿效的功能。

  • Java 命名與目錄接口(包括在 JDK 1.4 或更前的版本)
  • Java EE 平臺規范,查看其中的第5章:Naming(命名)

web.xml 配置

可在 Web 應用的部署描述符文件(/WEB-INF/web.xml)中使用下列元素來定義資源:

  •  應用的環境項。一個可用于配置應用運行方式的單值參數。
  •  資源引用,通常是引用保存某種資源的對象工廠,比如 JDBC DataSource 或 JavaMail Session 這樣的資源;或者引用配置在 Tomcat 中的自定義對象工廠中的資源。
  •  資源環境引用。Servlet 2.4 所添加的一種新 resource-ref,它簡化了不需要認證消息的資源的配置。

有了這些,Tomcat 就能利用適宜的資源工廠來創建資源,再也不需要其他配置信息了。Tomcat 將使用 /WEB-INF/web.xml 中的信息來創建資源。

另外,Tomcat 還提供了一些用于 JNDI 的特殊選項,它們沒有指定在 web.xml 中。比如,其中包括的 closeMethod 能在 Web 應用停止時,迅速清除 JNDI 資源;singleton 控制是否會在每次 JNDI 查找時創建資源的新實例。要想使用這些配置選項,資源必須指定在 Web 應用的  元素內,或者位于 $CATALINA_BASE/conf/server.xml 的  元素中。

context.xml 配置

如果 Tomcat 無法確定合適的資源工廠,并且/或者需要額外的配置信息,就必須在 Tomcat 創建資源之前指定好額外的具體配置。Tomcat 特定資源配置應位于  元素內,它可以指定在 $CATALINA_BASE/conf/server.xml,或者,最好放在每個 Web 應用的上下文 XML 文件中(META-INF/context.xml)。

要想完成 Tomcat 的特定資源配置,需要使用  元素中的下列元素:

  •  對將通過 JNDI 的 InitialContext 方法暴露給 Web 應用的環境項的名稱與數值加以配置(等同于 Web 應用部署描述符文件中包含了一個  元素)。
  • <Resource> 定義應用所能用到的資源名稱和數據類型(等同于 Web 應用部署描述符文件中包含了一個  元素)。
  •  添加一個鏈接,使其指向全局 JNDI 上下文中定義的資源。使用資源鏈接可以使 Web 應用訪問定義在  元素中子元素  中的資源。
  •  添加一個資源工廠,用于對從 java:comp/UserTransaction 獲得的 UserTransaction 接口進行實例化。

以上這些元素內嵌于  元素中,而且是與特定應用相關聯的。

如果資源已經定義在  元素中,那就不必再在部署描述符文件中定義它了。但建議在部署描述符文件中保留相關項,以便記錄應用資源需求。

加入同樣一個資源名稱既被定義在 Web 應用部署描述符文件的  元素中,又被定義在 Web 應用的  元素的  元素內,那么只有當相應的  元素允許時(將其中的 override 屬性設為 true),部署描述符文件中的值才會優先對待。

全局配置

Tomcat 為整個服務器維護著一個全局資源的獨立命名空間。這些全局資源配置在 $CATALINA_BASE/conf/server.xml 的  元素內。可以使用 將這些資源暴露給 Web 應用,以便在每一應用上下文中將其包含進來。

如果資源已經定義在  元素中,那就不必再在部署描述符文件中定義它了。但建議在部署描述符文件中保留相關項,以便記錄應用資源需求。

使用資源

當 Web 應用最初部署時,就配置 InitialContext,使其可被 Web 應用的各組件所使用(只讀訪問)。JNDI 命名空間的 java:comp/env 部分中包含著所有的配置項與資源,所以訪問資源(在下例中,就是一個 JDBC 數據源)應按如下形式進行:

// 獲取環境命名上下文

Context initCtx = new?InitialContext();

Context envCtx = (Context) initCtx.lookup("java:comp/env");

// 查找數據源

DataSource ds = (DataSource)

??envCtx.lookup("jdbc/EmployeeDB");

// 分配并使用池中的連接

Connection conn = ds.getConnection();

... use?this?connection?to?access?the?database?...conn.close();

Tomcat 標準資源工廠

Tomcat 包含一系列資源工廠,能為 Web 應用提供各種服務,而且無需修改 Web 應用或部署描述符文件即能靈活配置(通過  元素)。下面所列出的每一小節都詳細介紹了標準資源工廠的配置與用途。

要想了解如何創建、安裝、配置和使用你自己的自定義資源工廠類,請參看添加自定義資源工廠。

注意:在標準資源工廠中,只有“JDBC DataSource”和“User Transaction”工廠可適用于其他平臺,而且這些平臺必須實現了 Java EE 規范。而其他所有標準資源工廠,以及你自己編寫的自定義資源工廠,則都是 Tomcat 所專屬的,不適用于其他容器。

一般 JavaBean 資源

簡介

該資源工廠能創建出任何符合標準 JavaBean 命名規范1的 Java 類的對象。如果工廠的 singleton 屬性被設為 false,那么每當對該項進行 lookup 時,資源工廠將會創建出適合的 bean 類的新實例。

1. 標準的 JavaBean 命名規范,比如:構造函數沒有任何參數,屬性設置器遵守 setFoo() 命名模式,等等。

使用該功能所需的步驟將在下文介紹。

創建 JavaBean 類

創建一個 JavaBean 類,在每次查找資源工廠時,就創建它的實例。比如,假設你創建了一個名叫 com.mycompany.MyBean 的 JavaBean 類,如下所示:

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;
  }
}

聲明資源需求

接下來,修改 Web 應用部署描述符文件(/WEB-INF/web.xml),聲明 JNDI 名稱,并據此請求該 Bean 類的新實例。最簡單的方法是使用  元素,如下所示:

??Object factory for MyBean instances.

????bean/MyBeanFactory

? ? com.mycompany.MyBean

警告:一定要遵從 Web 應用部署描述符文件中 DTD 所需要的元素順序。關于這點,可參看Servlet 規范中的解釋。

使用資源

資源引用的典型用例如下所示:

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());

配置 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 必須跟部署描述符文件中所指定的值完全一樣。這里還初始化了 bar 屬性值,從而當返回新的 bean 時,setBar(23) 就會被調用。由于我們沒有初始化 foo 屬性(雖然我們完全可以這么做),所以 bean 依然采用構造函數中設置的默認值。

假設我們的 Bean 如下所示:

package?com.mycompany;
import?java.net.InetAddress;import?java.net.UnknownHostException;
public?class MyBean2 
??private?InetAddress local = null;
??public InetAddress getLocal() {

????return?local;

??}

?public void setLocal(InetAddress ip) {

????local = ip;

??}
??public void setLocal(String localHost) {

????try?{

??????local = InetAddress.getByName(localHost);

????} catch?(UnknownHostException ex) {

????}

??}
?private?InetAddress remote = null;

?public InetAddress getRemote() {

????return?remote;

??}

?public void setRemote(InetAddress ip) {

????remote = ip;

??}

public void host(String remoteHost) {

????try?{

??????remote = InetAddress.getByName(remoteHost);

????} catch?(UnknownHostException ex) {

????}

??}

}

該 Bean 有兩個 InetAddress 類型的屬性。第一個屬性 local 還有第二種 setter 方法,傳入的是一個字符串參數。默認 Tomcat BeanFactory 會使用自動偵測到的 setter 方法,并將其參數類型作為屬性類型,然后拋出一個 NamingException(命名異常),因為它還沒有準備好將給定字符串值轉化為 InetAddress。我們可以讓 Tomcat BeanFactory 使用其他的 setter 方法,如下所示:

<Context ...>
  ...
  <Resource name="bean/MyBeanFactory" auth="Container"
            type="com.mycompany.MyBean2"
            factory="org.apache.naming.factory.BeanFactory"
            forceString="local"
            local="localhost"/>
  ...</Context>

bean 屬性 remote 也可以從字符串中設置,但必須使用非標準方法 host。如下設置 local 和 remote:

<Context ...>
  ...
  <Resource name="bean/MyBeanFactory" auth="Container"
            type="com.mycompany.MyBean2"
            factory="org.apache.naming.factory.BeanFactory"
            forceString="local,remote=host"
            local="localhost"
            remote="tomcat.apache.org"/>
  ...</Context>

如上所示,可以利用逗號作分隔符,將多個屬性描述串聯在一起放在 forceString 中。每一屬性描述要么只包含屬性名,要么由 name = method 的結構所組成。對于前者的情況,BeanFactory 會直接調用屬性名的 setter 方法;而對于后者,則通過調用方法 method 來設置屬性名 name。對于 String 或基本類型,或者相應的基本包裝器類的屬性,不必使用 forceString。會自動偵測正確的 setter 并實施參數類型轉換。

UserDatabase 資源

簡介

UserDatabase 資源通常被配置成通過 UserDataBase Realm 所使用的全局資源。Tomcat 包含一個 UserDatabaseFactoory,能夠創建基于 XML 文件(通常是 tomcat-users.xml)的 UserDatabase 資源。

建立全局的 UserDataBase 資源的步驟如下。

創建/編輯 XML 文件

XML 文件通常位于 $CATALINA_BASE/conf/tomcat-users.xml,但也可以放在文件系統中的任何位置。我們建議把該文件放在 $CATALINA_BASE/conf。典型的 XML 應如下所示:

<?xml version='1.0' encoding='utf-8'?><tomcat-users>
  <role rolename="tomcat"/>
  <role rolename="role1"/>
  <user username="tomcat" password="tomcat" roles="tomcat"/>
  <user username="both" password="tomcat" roles="tomcat,role1"/>
  <user username="role1" password="tomcat" roles="role1"/></tomcat-users>

聲明資源

接下來,修改 $CATALINA_BASE/conf/server.xml 來創建基于此文件的 UserDataBase 資源。如下所示:

<Resource name="UserDatabase"
          auth="Container"
          type="org.apache.catalina.UserDatabase"
          description="User database that can be updated and saved"
          factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
          pathname="conf/tomcat-users.xml"
          readonly="false" />

屬性 pathname 可以采用絕對路徑或相對路徑。相對路徑意味著是相對于 $CATALINA_BASE。

readonly 屬性是可選屬性,如果不采用,則默認為 true。如果該 XML 文件可寫,那么當 Tomcat 開啟時,就會被修改。警告:當該文件被修改后,它會繼承 Tomcat 目前運行用戶的默認文件權限。所以要確保這樣做是否能保持應用的安全性。

配置 Realm

配置 UserDatabase Realm 以便使用該資源,詳情可參看 Realm 配置文檔

JavaMail 會話

簡介

很多 Web 應用都會把發送電子郵件作為系統的必備功能。JavaMail API 可以讓這一過程變得相對簡單些,但需要很多的配置細節,客戶端應用必須知道的(包括用于發送消息的 SMTP 主機的名稱)。

Tomcat 所包含的標準資源工廠可以為你創建 javax.mail.Session 會話實例,并且已經配置好連接到 SMTP 服務器上,從而使應用完全與電子郵件配置環境相隔離,不受后者變更的影響,無論何時,只需請求并接受預配置的會話即可。

所需步驟如下所示。

聲明資源需求

首先應該做的是修改 Web 應用的部署描述符文件(/WEB-INF/web.xml),聲明 JNDI 名稱以便借此查找預配置會話。按照慣例,所有這樣的名字都應該解析到 mail 子上下文(相對于標準的 java:comp/env 命名上下文而言的,這個命名上下文是所有資源工廠的基準。)典型的 web.xml 項應該如下所示:


????Resource reference to a factory for javax.mail.Session

????instances that may be used for sending electronic mail

????messages, preconfigured to connect to the appropriate

????SMTP server.

    mail/Session

????javax.mail.Session

????Container

??

警告:一定要遵從 Web 應用部署描述符文件中 DTD 所需要的元素順序。關于這點,可參看Servlet 規范中的解釋。

使用資源

資源引用的典型用例如下所示:

Context initCtx = new?InitialContext();

Context envCtx = (Context) initCtx.lookup("java:comp/env");

Session session = (Session) envCtx.lookup("mail/Session");



Message message = new?MimeMessage(session);

message.setFrom(new?InternetAddress(request.getParameter("from")));

InternetAddress to[] = new?InternetAddress[1];

to[0] = new?InternetAddress(request.getParameter("to"));

message.setRecipients(Message.RecipientType.TO, to);

message.setSubject(request.getParameter("subject"));

message.setContent(request.getParameter("content"), "text/plain");

Transport.send(message);

注意,該應用所用的資源引用名與 Web 應用部署符中聲明的完全相同。這是與下文會講到的  元素里所配置的資源工廠相匹配的。

配置 Tomcat 資源工廠

為了配置 Tomcat 的資源工廠,在  元素中添加以下元素:

<Context ...>
  ...
  <Resource name="mail/Session" auth="Container"
            type="javax.mail.Session"
            mail.smtp.host="localhost"/>
  ...</Context>

注意,資源名(在這里,是 mail/Session)必須與 Web 應用部署描述符文件中所指定的值相匹配。對于 mail.smtp.host 參數值,可以用為你的網絡提供 SMTP 服務的服務器來自定義。

額外的資源屬性與值將轉換成相關的屬性及值,并被傳入 javax.mail.Session.getInstance(java.util.Properties),作為參數集 java.util.Properties 中的一部分。除了 JavaMail 規范附件A中所定義的屬性之外,個別的提供者可能還支持額外的屬性。

如果資源配置中包含 password 屬性,以及 mail.smtp.user 或 mail.user 屬性,那么 Tomcat 資源工廠將配置并添加 javax.mail.Authenticator 到郵件會話中。

安裝 JavaMail 庫

下載 JavaMail API

解壓縮文件分發包,將 mail.jar 放到 $CATALINA_HOME/lib 中,從而使 Tomcat 能在郵件會話資源初始化期間能夠使用它。注意:不能將這一文件同時放在 $CATALINA_HOME/lib 和 Web 應用的 /lib 文件夾中,否則就會出錯,只能將其放在 $CATALINA_HOME/lib 中。

重啟 Tomcat

為了能讓 Tomcat 使用這個額外的 jar 文件,必須重啟 Tomcat 實例。

范例應用

Tomcat 中的 /examples 應用中帶有一個使用該資源工廠的范例。可以通過“JSP 范例”的鏈接來訪問它。實際發送郵件的 servlet 的源代碼則位于 /WEB-INF/classes/SendMailServlet.java 中。

警告:默認配置在 localhost 的 端口 25 上的 SMTP 服務器。如果實際情況不符,則需要編輯該 Web 應用的  元素,將 mail.smtp.host 參數的值修改為你的網絡上的 SMTP 服務器的主機名。

JDBC 數據源

簡介

許多 Web 應用都需要 JDBC 驅動來訪問數據庫,以便能夠支持該應用所需要的功能。Java EE 平臺規范要求 Java EE 應用服務器針對該需求提供一個 DataSource 實現(也就是說,用于 JDBC 連接的連接池)。Tomcat 就能提供同樣的支持,因此在 Tomcat 上,由于使用了這種服務,基于數據庫的應用可以不用修改就能移植到任何 Java EE 服務器上運行。

注意:Tomcat 默認所支持的數據源是基于 Commons 項目 的 DBCP 連接池。但也可以通過編寫自定義的資源工廠,使用其他實現了 javax.sql.DataSource 的連接池,詳見下文。

安裝 JDBC 驅動

使用 JDBC 數據源的 JNDI 資源工廠需要一個適合的 JDBC 驅動,要求它既能被 Tomcat 內部類所使用,也能被你的 Web 應用所使用。這很容易實現,只需將驅動的 JAR 文件(或多個文件)安裝到 $CATALINA_HOME/lib 目錄中即可,這樣資源工廠和應用就都能使用了這一驅動了。

聲明資源需求

下一步,修改 Web 應用的部署描述符文件(/WEB-INF/web.xml),聲明 JNDI 名稱以便借此查找預配置的數據源。按照慣例,所有這樣的名稱都應該在jdbc 子上下文中聲明(這個“子”是相對于標準的 java:comp/env 環境命名上下文而言的。java:comp/env 環境命名上下文是所有資源工廠的根引用)。典型的 web.xml 文件應如下所示:


????Resource reference to a factory for java.sql.Connection

????instances that may be used for talking to a particular

????database that is configured in the 

????configurartion for the web application.

????jdbc/EmployeeDB

????javax.sql.DataSource

????Container

警告:一定要遵從 Web 應用部署描述符文件中 DTD 所需要的元素順序。關于這點,可參看Servlet 規范中的解釋。

使用資源

資源引用的典型用例如下所示:

Context initCtx = new InitialContext();

Context envCtx = (Context) initCtx.lookup("java:comp/env");

DataSource ds = (DataSource)

??envCtx.lookup("jdbc/EmployeeDB");

Connection conn = ds.getConnection();

... use?this connection?to?access?the database?...

conn.close();

注意,該應用所用的資源引用名與 Web 應用部署符中聲明的完全相同。這是與下文會講到的  元素里所配置的資源工廠相匹配的。

配置 Tomcat 資源工廠

為了配置 Tomcat 的資源工廠,在  元素中添加以下元素:

<Context ...>
  ...
  <Resource name="jdbc/EmployeeDB"
            auth="Container"
            type="javax.sql.DataSource"
            username="dbusername"
            password="dbpassword"
            driverClassName="org.hsql.jdbcDriver"
            url="jdbc:HypersonicSQL:database"
            maxTotal="8"
            maxIdle="4"/>
  ...</Context>

注意上述代碼中的資源名(這里是 jdbc/EmployeeDB)必須跟 Web 應用部署描述符文件中指定的值相同。

該例假定使用的是 HypersonicSQL 數據庫 JDBC 驅動。可自定義 driverClassName 和 driverName 參數,使其匹配實際數據庫的 JDBC 驅動與連接 URL。

Tomcat 標準數據源資源工廠

(org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory)的配置屬性如下:

  • driverClassName 所用的 JDBC 驅動的完全合格的類名。
  • username JDBC 驅動所要接受的數據庫用戶名。
  • password JDBC 驅動所要接受的數據庫密碼。
  • url 傳入 JDBC 驅動的連接 URL(為了向后兼容性考慮,也同樣認可 driverName 屬性,即與之等同)。
  • initialSize 連接池初始化過程中所創建的初始連接的數目。默認為 0。
  • maxTotal 連接池同時所能分配的最大連接數。默認為 8。
  • minIdle 連接池中同時空閑的最少連接數。默認為 0。
  • maxIdle 連接池中同時空閑的最多連接數。默認為 8。
  • maxWaitMillis 在拋出異常前,連接池等待(沒有可用的連接)連接返回的最長等待毫秒數。默認為 -1(無限長時間)。

還有一些額外的用來驗證連接的屬性,如下所示:

  • validationQuery 在連接返回應用之前,連接池用于驗證連接的 SQL 查詢。如果指定了該屬性值,查詢必須是一個至少能返回一行的 SQL SELECT 語句。
  • validationQueryTimeout 驗證查詢返回的超時時間。默認為 -1(無限長時間)。
  • testOnBorrow 布爾值,true 或 false,針對每次從連接池中借出的連接,判斷是否應用驗證查詢對其驗證。默認:true。
  • testOnReturn 布爾值,true 或 false,針對每次歸還給連接池的連接,判斷是否應用驗證查詢對其驗證。默認:false。

可選的 evictor thread 會清除空閑較長時間的連接,從而縮小連接池。evictor thread 不受 minIdle 屬性值的空閑。注意,如果你只想通過配置的 minIdle 屬性來縮小連接池,那么不需要使用 evictor thread。

默認 evictor 是禁用的,另外,可以使用下列屬性來配置它:

  • timeBetweenEvictionRunsMillis evictor 線程連續運行之間的毫秒數。默認為 -1(禁止)
  • numTestsPerEvictionRun evictor 每次運行中,evictor 實施的用來檢測空閑與否的連接數目。默認為 3。
  • minEvictableIdleTimeMillis evictor 從連接池中清除某連接后的空閑時間,以毫秒計,默認為 30 * 60 * 1000(30分鐘)。
  • testWhileIdle 布爾值,true 或 false。對于在連接池中處于空閑狀態的連接,是否應被 evictor 線程通過驗證查詢來驗證。默認為false。

另一個可選特性是對廢棄連接的移除。如果應用很久都不把某個連接返回給連接池,那么該連接就被稱為廢棄連接。連接池就會自動關閉這樣的連接,并將其從池中移除。這么做是為了防止應用泄露連接。

默認是禁止廢棄連接的,可以通過下列屬性來配置:

  • removeAbandoned 布爾值,true 或 false。確定是否去除連接池中的廢棄連接。默認為 false。
  • removeAbandonedTimeout 經過多少秒后,借用的連接可以認為被廢棄。默認為 300。
  • logAbandoned 布爾值,true 或 false。確定是否需要針對廢棄了語句或連接的應用代碼來記錄堆棧跟蹤。如果記錄的話,將會帶來很大的開銷。默認為 false。

最后再介紹一些可以對連接池行為進行進一步微調的屬性:

  • defaultAutoCommit 布爾值,true 或 false。由連接池所創建的連接的默認自動提交狀態。默認為 true。
  • defaultReadOnly 布爾值,true 或 false。由連接池所創建的連接的默認只讀狀態。默認為 false。
  • defaultTransactionIsolation 設定默認的事務隔離級別。可取值為:NONE、READ_COMMITTED、READ_UNCOMMITTED、REPEATABLE_READ 與 SERIALIZABLE。沒有默認設置。
  • poolPreparedStatements 布爾值,true 或 false。 是否池化 PreparedStatements 和 CallableStatements。默認為 false。
  • maxOpenPreparedStatements 同時能被語句池分配的開放語句的最大數目。默認為 -1(無限)
  • defaultCatalog catalog 默認值。默認值:未設定。
  • connectionInitSqls 連接建立后運行的一系列 SQL 語句。各個語句間用分號(;)進行分隔。默認為:沒有語句。
  • connectionInitSqls 傳入驅動用于創建連接的驅動特定屬性。每一屬性都以 name = value 的形式給出,多個屬性用分號(;)進行分隔。默認:沒有屬性。
  • accessToUnderlyingConnectionAllowed 布爾值,true 或 false。 是否可訪問底層連接。默認為 false。

要想更詳細地了解這些屬性,請參閱 commons-dbcp 文檔。

添加自定義資源工廠

如果標準資源工廠無法滿足你的需求,你還可以自己編寫資源工廠,然后將其集成到 Tomcat 中,在 Web 應用的  元素中配置該工廠的使用方式。在下面的范例中,我們將創建一個資源工廠,只懂得如何 com.mycompany.MyBean bean

編寫資源工廠類

你必須編寫一個類來實現 JNDI 服務提供者 javax.naming.spi.ObjectFactory 接口。每次 Web 應用在綁定到該工廠(假設該工廠配置中,singleton = "false")的上下文項上調用 lookup() 時,就會調用 getObjectInstance() 方法,該方法有如下這些參數:

  • Object obj 創建一個能夠生成 MyBean 實例的資源工廠,需要像下面這樣來創建類:
package?com.mycompany;

import?java.util.Enumeration;import?java.util.Hashtable;import?javax.naming.Context;import?javax.naming.Name;import?javax.naming.NamingException;import?javax.naming.RefAddr;import?javax.naming.Reference;import?javax.naming.spi.ObjectFactory;

public?class MyBeanFactory implements ObjectFactory {

??public Object getObjectInstance(Object obj,

??????Name name, Context nameCtx, Hashtable environment)

??????throws NamingException {

??????// Acquire an instance of our specified bean class

??????MyBean bean = new?MyBean();

??????// Customize the bean properties from our attributes

??????Reference ref = (Reference) obj;

??????Enumeration addrs = ref.getAll();

??????while?(addrs.hasMoreElements()) {

??????????RefAddr addr = (RefAddr) addrs.nextElement();

??????????String name = addr.getType();

??????????String value = (String) addr.getContent();

??????????if?(name.equals("foo")) {

??????????????bean.setFoo(value);

??????????} else?if?(name.equals("bar")) {

??????????????try?{

??????????????????bean.setBar(Integer.parseInt(value));

??????????????} catch?(NumberFormatException e) {

??????????????????throw?new?NamingException("Invalid 'bar' value "?+ value);

??????????????}

??????????}

??????}


??????// Return the customized instance

??????return?(bean);

??}
}

// Acquire an instance of our specified bean class 需要我們所指定的bean 類的一個實例

// Customize the bean properties from our attributes 從屬性中自定義 bean 屬性。

// Return the customized instance 返回自定義實例

在上例中,無條件地創建了 com.mycompany.MyBean 類的一個新實例, 并根據工廠配置中的  元素(下文詳述)包括的參數來填充這一實例。你應該記住,必須忽略任何名為 factory 的參數——參數應該用來指定工廠類自身的名字(com.mycompany.MyBeanFactory),而不是配置的 bean 屬性。

關于 ObjectFactory 的更多信息,可參見 JNDI 服務提供者接口(SPI)規范。

首先參照一個 $CATALINA_HOME/lib 目錄中包含所有 JAR 文件的類路徑來編譯該類。完成之后,將這個工廠類以及相應的 Bean 類解壓縮到 $CATALINA_HOME/lib,或者 $CATALINA_HOME/lib 內的一個 JAR 文件中。這樣,所需的類文件就能被 Catalina 內部資源與 Web 應用看到了。

聲明資源需求

下一步,修改 Web 應用的部署描述符文件(/WEB-INF/web.xml),聲明 JNDI 名稱以便借此請求該 bean 的新實例。最簡單的方法是使用  元素,如下所示

   ?Object factory for MyBean instances.

????bean/MyBeanFactory

????com.mycompany.MyBean
警告:一定要遵從 Web 應用部署描述符文件中 DTD 所需要的元素順序。關于這點,可參看Servlet 規范中的解釋。

使用資源
資源引用的典型用例如下所示:

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());

配置 Tomcat 資源工廠

為了配置 Tomcat 的資源工廠,在  元素中添加以下元素:



?<Context ...>
  ...
  <Resource name="bean/MyBeanFactory" auth="Container"
            type="com.mycompany.MyBean"
            factory="com.mycompany.MyBeanFactory"
            singleton="false"
            bar="23"/>
  ...</Context>

注意上述代碼中的資源名(這里是 bean/MyBeanFactory)必須跟 Web 應用部署描述符文件中指定的值相同。另外,我們還初始化了 bar 屬性值,從而在返回新 bean 時,導致 setBar(23) 被調用。由于我們沒有初始化 foo 屬性(雖然完全可以這樣做),所以 bean 將含有構造函數所定義的各種默認值。

另外,你肯定能注意到,從應用開發者的角度來看,資源環境引用的聲明,以及請求新實例的編程方式,都跟通用 JavaBean 資源(Generic JavaBean Resources)范例所用方式如出一轍。這揭示了使用 JNDI 資源封裝功能的一個優點:只要維持兼容的 API,無需修改使用資源的應用,只需改變底層實現。

全部教程
主站蜘蛛池模板: 色婷婷综合在线视频最新 | 精品影视| 在线日本中文字幕 | 国产精品美女久久久久 | 国产精品爱啪在线线免费观看 | 曰本性l交视频 | 久草在线国产 | 亚洲精品乱码久久久久 | 久久99热久久精品99 | 中文字幕一区二区三区免费看 | 国产成人精品综合久久久软件 | 九九久久国产精品 | 五月天婷婷在线视频国产在线 | 成人午夜性a一级毛片美女 成人午夜性视频欧美成人 成人午夜亚洲影视在线观看 | 国产日韩精品一区在线观看播放 | 成人中文字幕一区二区三区 | 婷婷久久综合网 | 黄色直接观看 | 视频亚洲一区 | 成人a视频在线观看 | 手机看片福利盒子久久青 | 日韩在线操 | 色姑娘综合 | 色妞ww精品视频7777 | 五月激情综合婷婷 | 久久免费播放视频 | 成人特级毛片69免费观看 | 欧美综合图 | 国产91一区二这在线播放 | 深夜成人性视频免费看 | 神马影院我不卡在线观看 | 国产精品夜色一区二区三区 | 离线枕边人国语在线影视 | 加勒比色综合 | 久草在线观看免费 | 国产香蕉视频在线播放 | 久久久精品在观看999 | 成人免费高清视频 | 99爱在线精品视频免费观看9 | 午夜影院一区二区三区 | 九九精品久久 |