【问题标题】:How to use a JNDI Resource in a JAX-RS (Jersey) Application?如何在 JAX-RS (Jersey) 应用程序中使用 JNDI 资源?
【发布时间】:2011-12-20 12:57:17
【问题描述】:

我正在尝试通过 Tomcat JNDI 资源建立与我的数据库的连接。我今天看了很多文章,似乎找不到答案。

在我的 server.xml 我有:

  <GlobalNamingResources>
  <Resource name="jdbc/MyDB" auth="Container" type="javax.sql.DataSource"
      maxActive="100" maxIdle="30" maxWait="10000"
      username="tomcat" password="...."
      driverClassName="com.mysql.jdbc.Driver"
      url="jdbc:mysql://localhost:3333/tomcat?autoReconnect=true"/>

  .....
  </GlobalNamingResources>

在我的网络服务中,我尝试通过以下方式访问资源:

    InitialContext ctx = new InitialContext();
    DataSource data = (DataSource)ctx.lookup("java:comp/env/jdbc/MyDB");
    Connection conn = data.getConnection();

当我运行代码时,我得到了这个异常:

Nov 2, 2011 1:06:20 PM com.sun.jersey.spi.container.ContainerResponse  mapMappableContainerException
SEVERE: The exception contained within MappableContainerException could not be mapped to a response, re-throwing to the HTTP container
javax.naming.NameNotFoundException: Name jdbc is not bound in this Context
...

我的网络应用程序库和 tomcat 库中都有最新的 mysql-connector-java-5.1.18-bin.jar

你能帮我解决这个问题吗?

【问题讨论】:

  • 您找到解决方案了吗?我也在寻找一种方法来做到这一点
  • 我也在寻找解决方案
  • 添加了答案

标签: mysql jakarta-ee tomcat jndi jax-rs


【解决方案1】:

我使用这个代码,只有资源的名称,它可以工作:

private Connection getConnection(){
      final Context ctx = new InitialContext();
      final DataSource ds = (DataSource) ctx.lookup("jdbc/MyDB");
      if (ds != null)
      {
             return ds.getConnection();
      }
      else
      {

      }
}

【讨论】:

    【解决方案2】:

    我们只需要在 java: 之后提及 jndi 名称 在你的情况下:

    InitialContext ctx = new InitialContext();
    DataSource data = (DataSource)ctx.lookup("java:/jdbc/MyDB");
    Connection conn = data.getConnection();
    

    因为您在 server.xml 中配置如下:

    <GlobalNamingResources>
      <Resource name="jdbc/MyDB" auth="Container" type="javax.sql.DataSource"
          maxActive="100" maxIdle="30" maxWait="10000"
          username="tomcat" password="...."
          driverClassName="com.mysql.jdbc.Driver"
          url="jdbc:mysql://localhost:3333/tomcat?autoReconnect=true"/>
    
      .....
      </GlobalNamingResources>
    

    【讨论】:

      【解决方案3】:

      我的解决方案是切换到数据库信息的属性文件,然后将其与实体管理器一起使用。

      import java.io.FileReader;
      import java.util.Arrays;
      import java.util.Collections;
      import java.util.Comparator;
      import java.util.HashMap;
      import java.util.List;
      import java.util.Map;
      import java.util.Properties;
      import java.util.Set;
      
      import javax.persistence.EntityManager;
      import javax.persistence.EntityManagerFactory;
      import javax.persistence.Persistence;
      import javax.servlet.ServletException;
      
      import org.eclipse.persistence.config.EntityManagerProperties;
      import org.eclipse.persistence.config.PersistenceUnitProperties;
      
      ...
      
              Properties properties = new Properties();
              FileReader fr = new FileReader(Constants.Config.getPropertiesFile());
              properties.load(fr);
      
      
              // connect to the database
              Map<String,String> emMap = new HashMap<String,String>();
              emMap.put(PersistenceUnitProperties.APP_LOCATION, Constants.Config.getAppDir());        
              emMap.put(EntityManagerProperties.JDBC_USER, properties.getProperty("db.username"));
              emMap.put(EntityManagerProperties.JDBC_PASSWORD, properties.getProperty("db.password"));
              // iterate over these properties attempting to read them in and connect to the url
              List<?> dbProps = Collections.list(properties.keys());
              Collections.sort(dbProps, new Comparator<Object>() {
                  @Override
                  public int compare(Object o1, Object o2) {
                      return o1.toString().compareTo(((String)o2));
                  }
              });
      
              for(Object propKey : dbProps){
                  // support multiple database key/values in the eform db.url, db.url1, ...  db.urlN
                  if(!propKey.toString().matches("db.url\\d*")){
                      continue;
                  }
                  String dbLocation = properties.getProperty(propKey.toString());
                  try {
                      if(dbLocation == null) continue;
      
                      emMap.put(EntityManagerProperties.JDBC_URL, dbLocation);
                      EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("db", emMap);
                      em = entityManagerFactory.createEntityManager();
                      // ensure we're connected by executing a no-op query
                      em.createNativeQuery("select current_database()").getSingleResult(); // will only work for postgresql
                      properties.put("db.connected", dbLocation);
                      break;
                    }
                    catch (javax.persistence.PersistenceException e) {
                      Utility.logger(DataHolder.class).error("Couldn't connect to " + dbLocation);
                    }
              }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-02-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-11
        • 2019-01-08
        • 1970-01-01
        • 2013-05-20
        相关资源
        最近更新 更多