1.
在
Tomcat
中添加
JNDI
数据源
建议用 Tomcat 的 Adiminstration 添加。在默认情况下, Tomcat 没有安装 administration 组件,详细安装步骤请参考《 Install the component Admin for tomcat 》。
登陆 http://localhost:8080/admin, 进入 Resources -> Data Sources -> Create New Data Source
设置 JNDI 参数:(这里以 MySql 为例)
JNDI Name:jdbc/mysql(JNDI 名随便起 )
Data Source URL:jdbc:mysql://localhost:3306/test (这里 test 是数据库名,当然后面还可以带其他参数,如: jdbc: mysql://localhost:3306/test?user=root&password=&useUnicode=true& characterEncoding=gbk&autoReconnect=true&failOverReadOnly=false )
JDBC Driver Class:com.mysql.jdbc.Driver (要把相应的驱动 jar 包放到 $TOMCAT_HOME$/common/lib )
User Name:root (用户名)
Password:***** (密码)
Max. Active Connections:4
Max. Idle Connections:2
Max. Wait for Connection:5000
2. 在 Web 项目中配置 resouce-ref
在项目的 web.xml 的根节点下添加以下内容:
<resource-ref>
<res-ref-name>jdbc/mysql</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
注意:这里 res-ref-name 必须与在 tomcat 中设置的 JNDI Name:jdbc/mysql(JNDI 名随便起 ) 一致。
3. 设置 $TOMCAT_HOME$/conf/server.xml
因为 TOMCAT 不会自动将 Data Source Resource 信息加到 Context 中,所以经常会忽略这一步
当前 server.xml 的内容为:
<?xml version="1.0" encoding="UTF-8"?>
<Server>
<Listener className="org.apache.catalina.core.AprLifecycleListener"/>
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
<Listener className="org.apache.catalina.storeconfig.StoreConfigLifecycleListener"/>
<Listener className="org.apache.catalina.mbeans.ServerLifecycleListener"/>
<GlobalNamingResources>
<Environment
name="simpleValue"
type="java.lang.Integer"
value="30"/>
<Resource
auth="Container"
description="User database that can be updated and saved"
name="UserDatabase"
type="org.apache.catalina.UserDatabase"
pathname="conf/tomcat-users.xml"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"/>
<Resource
name="jdbc/mysql"
type="javax.sql.DataSource"
password="123456"
driverClassName="com.mysql.jdbc.Driver"
maxIdle="2"
maxWait="5000"
username="root"
url="jdbc:mysql://localhost:3306/test"
maxActive="4"/>
</GlobalNamingResources>
<Service
name="Catalina">
<Connector
port="8080"
redirectPort="8443"
minSpareThreads="25"
connectionTimeout="60000"
connectionLinger="-1"
serverSoTimeout="0"
maxSpareThreads="75"
maxThreads="150"
tcpNoDelay="true"
maxHttpHeaderSize="8192">
</Connector>
<Connector
port="8009"
redirectPort="8443"
protocol="AJP/1.3">
</Connector>
<Engine
defaultHost="localhost"
name="Catalina">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"/>
<Host
appBase="webapps"
name="localhost">
<Context
docBase="/test"
path="/test"
reloadable="true"
debug="5"
crossContext="true">
<Resource
name="jdbc/mysql"
type="javax.sql.DataSource"
password="123456"
maxIdle="2"
maxWait="5000"
username="root"
maxActive="4"
/>
</Context>
</Host>
</Engine>
</Service>
</Server>
如果不更改该 server.xml 文件,使用 jdbc/mysql 时抛 exception Cannot create JDBC driver of class '' for connect URL 'null' 。
留意代码最后的 resource
<Context
docBase="/test"
path="/test"
reloadable="true"
debug="5"
crossContext="true">
<Resource
name="jdbc/mysql"
type="javax.sql.DataSource"
password="123456"
maxIdle="2"
maxWait="5000"
username="root"
maxActive="4"
/>
</Context>
发现在 <Resource /> 标签中没包含属性 driverClassName 和 url ,这是抛 Exception Cannot create JDBC driver of class '' for connect URL 'null' 的原因。
我们只需要将 <GlobalNamingResources></GlobalNamingResources> 中相应的 Resource
<Resource
name="jdbc/mysql"
type="javax.sql.DataSource"
password="123456"
driverClassName="com.mysql.jdbc.Driver"
maxIdle="2"
maxWait="5000"
username="root"
url="jdbc:mysql://localhost:3306/test"
maxActive="4"/>
替换掉 Context 下的 resource 即可。
更改后的 server.xml 文件内容为:
<?xml version="1.0" encoding="UTF-8"?>
<Server>
<Listener className="org.apache.catalina.core.AprLifecycleListener"/>
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
<Listener className="org.apache.catalina.storeconfig.StoreConfigLifecycleListener"/>
<Listener className="org.apache.catalina.mbeans.ServerLifecycleListener"/>
<GlobalNamingResources>
<Environment
name="simpleValue"
type="java.lang.Integer"
value="30"/>
<Resource
auth="Container"
description="User database that can be updated and saved"
name="UserDatabase"
type="org.apache.catalina.UserDatabase"
pathname="conf/tomcat-users.xml"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"/>
<Resource
name="jdbc/mysql"
type="javax.sql.DataSource"
password="123456"
driverClassName="com.mysql.jdbc.Driver"
maxIdle="2"
maxWait="5000"
username="root"
url="jdbc:mysql://localhost:3306/test"
maxActive="4"/>
</GlobalNamingResources>
<Service
name="Catalina">
<Connector
port="8080"
redirectPort="8443"
minSpareThreads="25"
connectionTimeout="60000"
connectionLinger="-1"
serverSoTimeout="0"
maxSpareThreads="75"
maxThreads="150"
tcpNoDelay="true"
maxHttpHeaderSize="8192">
</Connector>
<Connector
port="8009"
redirectPort="8443"
protocol="AJP/1.3">
</Connector>
<Engine
defaultHost="localhost"
name="Catalina">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"/>
<Host
appBase="webapps"
name="localhost">
<Context
docBase="/test"
path="/test"
reloadable="true"
debug="5"
crossContext="true">
<Resource
name="jdbc/mysql"
type="javax.sql.DataSource"
password="123456"
driverClassName="com.mysql.jdbc.Driver"
maxIdle="2"
maxWait="5000"
username="root"
url="jdbc:mysql://localhost:3306/test"
maxActive="4"/>
</Context>
</Host>
</Engine>
</Service>
</Server>
4. 在 java 代码中使用 JNDI 资源获得 DataSource
javax.naming.InitialContext ctx = new javax.naming.InitialContext();
DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/mysql");
Connection conn = ds.getConnection();
该代码在 JDK1.5 下测试通过
在一些资料中提到,在 JDK1.5 以前的版本可以通过
DataSource ds = (DataSource) ctx.lookup("jdbc/mysql");
获得 DataSource 。
我没测试过该代码。
上述代码在 J2EE 服务器环境下工作得很好,但是在 main() 中就会报一个 NoInitialContextException 。
之所以有 NoInitialContextException 是因为无法从 System.properties 中获得必要的 JNDI 参数,在服务器环境下,服务器启动时就把这些参数放到 System.properties 中。
所以可以通过以下方法解决:
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL,"t3://localhost:7001");
InitialContext ctx = new InitialContext(env);
或
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
System.setProperty(Context.PROVIDER_URL, "rmi://localhost:3306/test");
System.setProperty(Context.SECURITY_PRINCIPAL, "root");
System.setProperty(Context.SECURITY_CREDENTIALS, "123456");
以上代码建议改为在配置文件中配置
java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory
java.naming.provider.url=rmi://localhost:3306/test
java.naming.security.principal=user
java.naming.security.credentials=password
建议用 Tomcat 的 Adiminstration 添加。在默认情况下, Tomcat 没有安装 administration 组件,详细安装步骤请参考《 Install the component Admin for tomcat 》。
登陆 http://localhost:8080/admin, 进入 Resources -> Data Sources -> Create New Data Source
设置 JNDI 参数:(这里以 MySql 为例)
JNDI Name:jdbc/mysql(JNDI 名随便起 )
Data Source URL:jdbc:mysql://localhost:3306/test (这里 test 是数据库名,当然后面还可以带其他参数,如: jdbc: mysql://localhost:3306/test?user=root&password=&useUnicode=true& characterEncoding=gbk&autoReconnect=true&failOverReadOnly=false )
JDBC Driver Class:com.mysql.jdbc.Driver (要把相应的驱动 jar 包放到 $TOMCAT_HOME$/common/lib )
User Name:root (用户名)
Password:***** (密码)
Max. Active Connections:4
Max. Idle Connections:2
Max. Wait for Connection:5000
2. 在 Web 项目中配置 resouce-ref
在项目的 web.xml 的根节点下添加以下内容:
<resource-ref>
<res-ref-name>jdbc/mysql</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
注意:这里 res-ref-name 必须与在 tomcat 中设置的 JNDI Name:jdbc/mysql(JNDI 名随便起 ) 一致。
3. 设置 $TOMCAT_HOME$/conf/server.xml
因为 TOMCAT 不会自动将 Data Source Resource 信息加到 Context 中,所以经常会忽略这一步
当前 server.xml 的内容为:
<?xml version="1.0" encoding="UTF-8"?>
<Server>
<Listener className="org.apache.catalina.core.AprLifecycleListener"/>
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
<Listener className="org.apache.catalina.storeconfig.StoreConfigLifecycleListener"/>
<Listener className="org.apache.catalina.mbeans.ServerLifecycleListener"/>
<GlobalNamingResources>
<Environment
name="simpleValue"
type="java.lang.Integer"
value="30"/>
<Resource
auth="Container"
description="User database that can be updated and saved"
name="UserDatabase"
type="org.apache.catalina.UserDatabase"
pathname="conf/tomcat-users.xml"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"/>
<Resource
name="jdbc/mysql"
type="javax.sql.DataSource"
password="123456"
driverClassName="com.mysql.jdbc.Driver"
maxIdle="2"
maxWait="5000"
username="root"
url="jdbc:mysql://localhost:3306/test"
maxActive="4"/>
</GlobalNamingResources>
<Service
name="Catalina">
<Connector
port="8080"
redirectPort="8443"
minSpareThreads="25"
connectionTimeout="60000"
connectionLinger="-1"
serverSoTimeout="0"
maxSpareThreads="75"
maxThreads="150"
tcpNoDelay="true"
maxHttpHeaderSize="8192">
</Connector>
<Connector
port="8009"
redirectPort="8443"
protocol="AJP/1.3">
</Connector>
<Engine
defaultHost="localhost"
name="Catalina">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"/>
<Host
appBase="webapps"
name="localhost">
<Context
docBase="/test"
path="/test"
reloadable="true"
debug="5"
crossContext="true">
<Resource
name="jdbc/mysql"
type="javax.sql.DataSource"
password="123456"
maxIdle="2"
maxWait="5000"
username="root"
maxActive="4"
/>
</Context>
</Host>
</Engine>
</Service>
</Server>
如果不更改该 server.xml 文件,使用 jdbc/mysql 时抛 exception Cannot create JDBC driver of class '' for connect URL 'null' 。
留意代码最后的 resource
<Context
docBase="/test"
path="/test"
reloadable="true"
debug="5"
crossContext="true">
<Resource
name="jdbc/mysql"
type="javax.sql.DataSource"
password="123456"
maxIdle="2"
maxWait="5000"
username="root"
maxActive="4"
/>
</Context>
发现在 <Resource /> 标签中没包含属性 driverClassName 和 url ,这是抛 Exception Cannot create JDBC driver of class '' for connect URL 'null' 的原因。
我们只需要将 <GlobalNamingResources></GlobalNamingResources> 中相应的 Resource
<Resource
name="jdbc/mysql"
type="javax.sql.DataSource"
password="123456"
driverClassName="com.mysql.jdbc.Driver"
maxIdle="2"
maxWait="5000"
username="root"
url="jdbc:mysql://localhost:3306/test"
maxActive="4"/>
替换掉 Context 下的 resource 即可。
更改后的 server.xml 文件内容为:
<?xml version="1.0" encoding="UTF-8"?>
<Server>
<Listener className="org.apache.catalina.core.AprLifecycleListener"/>
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
<Listener className="org.apache.catalina.storeconfig.StoreConfigLifecycleListener"/>
<Listener className="org.apache.catalina.mbeans.ServerLifecycleListener"/>
<GlobalNamingResources>
<Environment
name="simpleValue"
type="java.lang.Integer"
value="30"/>
<Resource
auth="Container"
description="User database that can be updated and saved"
name="UserDatabase"
type="org.apache.catalina.UserDatabase"
pathname="conf/tomcat-users.xml"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"/>
<Resource
name="jdbc/mysql"
type="javax.sql.DataSource"
password="123456"
driverClassName="com.mysql.jdbc.Driver"
maxIdle="2"
maxWait="5000"
username="root"
url="jdbc:mysql://localhost:3306/test"
maxActive="4"/>
</GlobalNamingResources>
<Service
name="Catalina">
<Connector
port="8080"
redirectPort="8443"
minSpareThreads="25"
connectionTimeout="60000"
connectionLinger="-1"
serverSoTimeout="0"
maxSpareThreads="75"
maxThreads="150"
tcpNoDelay="true"
maxHttpHeaderSize="8192">
</Connector>
<Connector
port="8009"
redirectPort="8443"
protocol="AJP/1.3">
</Connector>
<Engine
defaultHost="localhost"
name="Catalina">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"/>
<Host
appBase="webapps"
name="localhost">
<Context
docBase="/test"
path="/test"
reloadable="true"
debug="5"
crossContext="true">
<Resource
name="jdbc/mysql"
type="javax.sql.DataSource"
password="123456"
driverClassName="com.mysql.jdbc.Driver"
maxIdle="2"
maxWait="5000"
username="root"
url="jdbc:mysql://localhost:3306/test"
maxActive="4"/>
</Context>
</Host>
</Engine>
</Service>
</Server>
4. 在 java 代码中使用 JNDI 资源获得 DataSource
javax.naming.InitialContext ctx = new javax.naming.InitialContext();
DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/mysql");
Connection conn = ds.getConnection();
该代码在 JDK1.5 下测试通过
在一些资料中提到,在 JDK1.5 以前的版本可以通过
DataSource ds = (DataSource) ctx.lookup("jdbc/mysql");
获得 DataSource 。
我没测试过该代码。
上述代码在 J2EE 服务器环境下工作得很好,但是在 main() 中就会报一个 NoInitialContextException 。
之所以有 NoInitialContextException 是因为无法从 System.properties 中获得必要的 JNDI 参数,在服务器环境下,服务器启动时就把这些参数放到 System.properties 中。
所以可以通过以下方法解决:
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL,"t3://localhost:7001");
InitialContext ctx = new InitialContext(env);
或
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
System.setProperty(Context.PROVIDER_URL, "rmi://localhost:3306/test");
System.setProperty(Context.SECURITY_PRINCIPAL, "root");
System.setProperty(Context.SECURITY_CREDENTIALS, "123456");
以上代码建议改为在配置文件中配置
java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory
java.naming.provider.url=rmi://localhost:3306/test
java.naming.security.principal=user
java.naming.security.credentials=password