1. 程式人生 > >JNDI學習總結(二):tomcat配置全域性和私有JNDI資料來源的幾種方式

JNDI學習總結(二):tomcat配置全域性和私有JNDI資料來源的幾種方式

下面介紹幾種常用的JNDI資料來源配置方式

環境:IDEA+tomcat7

全域性:

1. 修改tomcat的context.xml的<context>標籤

  在<context>標籤內加入如下內容(以配置mysql資料來源為例):

<Resource name="jdbc/mysql"     //名稱可以自定義
    auth="Container" 
    type="javax.sql.DataSource" 
    username=""   //改成自己的資料庫使用者名稱和密碼
    password="" 
    maxIdle="30" 
    maxWait="10000" 
    maxActive="100"
    driverClassName="com.mysql.jdbc.Driver"
    url="jdbc:mysql://localhost:3306/資料庫名" />

    配置好後重啟tomcat。 可以選擇在專案中引入mysql驅動,或者直接將驅動jar包扔進tomcat安裝目錄中的lib資料夾下。

    最後在專案的web.xml中配置這段程式碼(其實可有可無,但最好加上,後文會解釋原因):

<resource-ref>
    <res-ref-name>jdbc/mysql</res-ref-name> //和上面的name屬性值相同
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
    <res-sharing-scope>Shareable</res-sharing-scope>
  </resource-ref>

    使用下面這段程式碼測試(注意,不能在main中測試,否則會報錯。在jsp頁面中或者servlet中可以,需要web環境):

Context initial = new InitialContext(); //得到上下文引用
DataSource datasource = (DataSource) initial.lookup("java:comp/env/jdbc/mysql");

2. 修改tomcat的server.xml的<GlobalNamingResources>

在<GlobalNamingResources>標籤中加入下面程式碼:

<Resource name="globalResourceTest" 
    auth="Container" 
    type="javax.sql.DataSource" 
    username=""
    password="" 
    maxIdle="30" 
    maxWait="10000" 
    maxActive="100"
    driverClassName="com.mysql.jdbc.Driver"
    url="jdbc:mysql://localhost:3306/資料庫名" /> 

    開啟$tomcat_home\conf\context.xml, 在<context>標籤中加入下面程式碼:

<ResourceLink name="jdbc/mysql" global="globalResource" type="javax.sql.DataSource"/>

    注意:<Resource>中的name屬性要和<ResourceLink>中的global屬性對應才能引用到,<ResourceLink>中的name才是資料來源的名字,要通過這個名字找到資料來源。

    同樣在web.xml中加入下面程式碼:

<resource-ref>
    <res-ref-name>jdbc/mysql</res-ref-name> //和上面的name屬性值相同
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
    <res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>

私有:

1. 修改tomcat的server.xml的<Host>

找到<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true"></Host>,在其中加入以下內容:

<Context path="/xxxx" docBase="專案的絕對路徑" reloadable="true">
    <Resource name="jdbc/mysql" 
        auth="Container" 
	type="javax.sql.DataSource" 
	username="" 
	password="" 
	maxIdle="30" 
	maxWait="10000" 
	maxActive="100"
	driverClassName="com.mysql.jdbc.Driver"
	url="jdbc:mysql://127.0.0.1:3306/資料庫名"/>
</Context>

注意:<context>的path屬性必須和專案訪問路徑一致且開頭必須加“/”。 什麼叫專案訪問路徑?如果你用eclipse+tomcat啟動專案,那path屬性為“/你的專案名”。 若你使用IDEA+tomcat啟動專案,這裡的path必須等於下圖圈起來的地方:

, 不然獲取不到資料來源。

若在IDE中啟動tomcat,其實docBase這個屬性設不設定都可以,設定了亂填也不影響。但為什麼我還是寫上了,因為當你使用cmd啟動tomcat時,若不設定該屬性啟動時會丟擲“NamingException: No naming context bound to this class loader”。所以必須將docBase設定為專案的絕對路徑。

然後在web.xml中加入:

<resource-ref>
    <res-ref-name>jdbc/mysql</res-ref-name> //和上面的name屬性值相同
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
    <res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>

2. 在專案的META-INF資料夾下建立context.xml

內容如下:

<?xml version="1.0" encoding="UTF-8"?>
<Context reloadable="true">
    <Resource name="jdbc/mysql" 
        auth="Container" 
	type="javax.sql.DataSource" 
	username="" 
	password="" 
	maxIdle="30" 
	maxWait="10000" 
	maxActive="100"
	driverClassName="com.mysql.jdbc.Driver"
	url="jdbc:mysql://127.0.0.1:3306/專案名"/>
</Context>

同時存在多種配置方式且同名,會獲取哪一個:

首先,全域性配置大於私有配置,也就是說若全域性和私有同時存在,優先獲取全域性配置的資料來源

全域性:

    在context.xml中,<Resource>和<ResourceLink>(引用server.xml中<GlobalNamingResources> )同時存在,哪個標籤在前獲取到哪一個,即按順序獲取。

私有:

    1. 若只存在<Host>標籤中的配置,不存在META-INF中的context.xml,則優先獲取<Host>中配置的第一個資料來源。

    2. 若兩種私有配置方式都存在,會獲取META-INF中context.xml配置的資料來源。

為什麼web.xml中的配置可有可無,卻要加上呢?

詳情見tomcat的docs:jndi-resources-howto.html

其中有這麼一句話:

If a resource has been defined in a <Context> element it is not necessary for that resource to be defined in /WEB-INF/web.xml. However, it is recommended to keep the entry in /WEB-INF/web.xml to document the resource requirements for the web application.

也就是說,在web.xml加入的那段程式碼僅起到說明作用,說明這個Web應用引用了哪些資源!詳情請翻閱文件