Tomcat JNDI配置

来源:互联网 发布:solidworks模型的数据 编辑:程序博客网 时间:2024/05/18 14:26

1.Tomcat中添加JNDI数据源
建议用TomcatAdiminstration添加。在默认情况下,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 />标签中没包含属性driverClassNameurl,这是抛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