Exemplo de Tomcat DataSource JNDI em Java

Bem-vindo ao Tutorial de Exemplo do Tomcat DataSource JNDI. Analisamos o JDBC DataSource no último tutorial e aprendemos como usá-lo em um aplicativo Java independente.

Tomcat DataSource JNDI

O benefício real do DataSource é percebido quando o utilizamos com um Contexto JNDI. Por exemplo, um pool de conexões em um aplicativo da web implantado em um contêiner de servlets. A maioria dos populares contêineres de servlets oferece suporte integrado para DataSource por meio de configuração de Recursos e contexto JNDI. Isso nos ajuda a criar e usar um pool de conexões DataSource com apenas algumas linhas de configuração. Este tutorial tem como objetivo fornecer um exemplo de configuração do Tomcat DataSource JNDI. O Apache Tomcat oferece três maneiras de configurar o DataSource no contexto JNDI.

  1. Ficheiro context.xml da aplicação – Esta é a maneira mais fácil de configurar o DataSource, tudo o que precisamos é de um ficheiro context.xml no diretório META-INF. Temos que definir o elemento Resource no ficheiro de contexto e o contentor irá encarregar-se de carregá-lo e configurá-lo. A abordagem é simples, mas tem algumas desvantagens;
    • Já que o ficheiro de contexto está incluído no ficheiro WAR, precisamos de construir e implementar um novo WAR para cada pequena mudança de configuração. O mesmo problema surge se a sua aplicação funcionar num ambiente distribuído ou se a sua aplicação precisar de ser implementada em diferentes ambientes de teste, como QA, TI, PROD, etc.
    • O datasource é criado pelo contentor apenas para uso da aplicação, portanto, não pode ser usado globalmente. Não podemos partilhar o datasource entre várias aplicações.
    • Se existir um datasource global (server.xml) definido com o mesmo nome, o datasource da aplicação é ignorado.
  2. Contexto do servidor.xml – Se houver várias aplicações no servidor e você quiser compartilhar o DataSource entre elas, podemos definir isso no arquivo contexto do servidor.xml. Este arquivo está localizado no diretório apache-tomcat/conf. O escopo do arquivo contexto do servidor.xml é de aplicação, então se você definir um pool de conexão DataSource de 100 conexões e houver 20 aplicações, o DataSource será criado para cada uma das aplicações. Isso resultará em 2000 conexões que obviamente consumirão todos os recursos do servidor de banco de dados e prejudicarão o desempenho da aplicação.
  3. server.xml e contexto do servidor.xml – Podemos definir DataSource em nível global ao defini-los no elemento GlobalNamingResources do server.xml. Se usarmos esta abordagem, então precisamos definir um ResourceLink no arquivo contexto do servidor ou específico da aplicação. Esta é a maneira preferida quando você deseja compartilhar um pool de recursos comum entre várias aplicações em execução no servidor. Em relação ao link de recurso, se deve defini-lo no arquivo contexto do servidor em nível de servidor ou em nível de aplicativo, depende de seus requisitos.

Vamos para o exemplo de JNDI do Tomcat DataSource em uma aplicação web Java. Para a configuração dos dados de teste, consulte meu último artigo sobre Exemplo de DataSource JDBC.

Exemplo de Configuração JNDI do DataSource do Tomcat – server.xml

Adicione o código abaixo no arquivo server.xml do Tomcat. O código deve ser adicionado no elemento GlobalNamingResources. Certifique-se também de que o driver do banco de dados esteja presente no diretório lib do Tomcat, então neste caso o arquivo jar jdbc do mysql deve estar presente no diretório lib do Tomcat.

<Resource name="jdbc/MyDB" 
      global="jdbc/MyDB" 
      auth="Container" 
      type="javax.sql.DataSource" 
      driverClassName="com.mysql.jdbc.Driver" 
      url="jdbc:mysql://localhost:3306/UserDB" 
      username="pankaj" 
      password="pankaj123" 
      
      maxActive="100" 
      maxIdle="20" 
      minIdle="5" 
      maxWait="10000"/>

Aqui estamos criando um contexto JNDI com o nome jdbc/MyDB que é um tipo de DataSource. Estamos passando as configurações do banco de dados nos atributos url, nome de usuário, senha e driverClassName. As propriedades de pooling de conexão são definidas nos atributos maxActive, maxIdle e minIdle.

Adicione o código abaixo no arquivo context.xml do servidor.

<ResourceLink name="jdbc/MyLocalDB"
                global="jdbc/MyDB"
                auth="Container"
                type="javax.sql.DataSource" />

Observe que o nome do link de recurso é diferente do link global, devemos usar este nome em nosso programa Java para obter o DataSource.

Exemplo de Tomcat DataSource JNDI

Crie uma aplicação web dinâmica com o nome JDBCDataSourceTomcat e então crie um Servlet com o código abaixo.

package com.journaldev.jdbc.datasource;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

@WebServlet("/JDBCDataSourceExample")
public class JDBCDataSourceExample extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		Context ctx = null;
		Connection con = null;
		Statement stmt = null;
		ResultSet rs = null;
		try{
			ctx = new InitialContext();
			DataSource ds = (DataSource) ctx.lookup("java:/comp/env/jdbc/MyLocalDB");
			
			con = ds.getConnection();
			stmt = con.createStatement();
			
			rs = stmt.executeQuery("select empid, name from Employee");
			
			PrintWriter out = response.getWriter();
            response.setContentType("text/html");
            out.print("

Employee Details

"); out.print(""); out.print(""); out.print(""); while(rs.next()) { out.print(""); out.print(""); out.print(""); out.print(""); } out.print("
Employee IDEmployee Name
" + rs.getInt("empid") + "" + rs.getString("name") + "

"); //vamos imprimir algumas informações do BD out.print("

Database Details

"); out.print("Database Product: "+con.getMetaData().getDatabaseProductName()+"
"); out.print("Database Driver: "+con.getMetaData().getDriverName()); out.print(""); }catch(NamingException e){ e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); }finally{ try { rs.close(); stmt.close(); con.close(); ctx.close(); } catch (SQLException e) { System.out.println("Exception in closing DB resources"); } catch (NamingException e) { System.out.println("Exception in closing Context"); } } } }

Observe que estou usando configuração baseada em anotações Servlet 3 e funcionará no Tomcat 7 ou versões superiores. Se você estiver usando uma versão mais baixa do Tomcat, será necessário fazer algumas modificações no código do servlet para remover a anotação WebServlet e configurar no arquivo web.xml. A parte do código do servlet que estamos interessados em;

ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("java:/comp/env/jdbc/MyLocalDB");

Esta é a maneira de obter os recursos JNDI definidos para serem usados pela aplicação. Poderíamos ter escrito da seguinte maneira também;

ctx = new InitialContext();
Context initCtx  = (Context) ctx.lookup("java:/comp/env");
DataSource ds = (DataSource) initCtx.lookup("jdbc/MyLocalDB");

I am also printing some database information to check which database we are connected. Now when you will run the application, you will see following output. Let’s see how easy it is to switch the database server because we are using Tomcat DataSource. All you need is to change the Database properties. So if we have to switch to Oracle database, my Resource configuration will look like below.

<Resource name="jdbc/MyDB" 
      global="jdbc/MyDB" 
      auth="Container" 
      type="javax.sql.DataSource" 
      driverClassName="oracle.jdbc.driver.OracleDriver" 
      url="jdbc:oracle:thin:@localhost:1521:orcl" 
      username="hr" 
      password="oracle" 
      
      maxActive="100" 
      maxIdle="20" 
      minIdle="5" 
      maxWait="10000"/>

E quando reiniciamos o servidor e executamos a aplicação, ela se conectará ao banco de dados Oracle e produzirá o seguinte resultado. Isso é tudo para o exemplo de configuração de Tomcat DataSource JNDI, você pode definir o recurso de forma semelhante nos arquivos context.xml também.

Source:
https://www.digitalocean.com/community/tutorials/tomcat-datasource-jndi-example-java