Bem-vindo ao Tutorial de Exemplo do Tomcat DataSource JNDI. Nós exploramos o JDBC DataSource no último tutorial e aprendemos como utilizá-lo em um aplicativo Java autônomo.
Tomcat DataSource JNDI
O benefício real do DataSource surge quando o utilizamos com um Contexto JNDI. Por exemplo, um pool de conexões em um aplicativo web implantado em um contêiner de servlets. A maioria dos contêineres de servlets populares oferece suporte embutido 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.
- Contexto do aplicativo.xml – Esta é a maneira mais fácil de configurar o DataSource, tudo o que precisamos é de um arquivo context.xml no diretório META-INF. Devemos definir o elemento Resource no arquivo de contexto e o contêiner se encarregará de carregá-lo e configurá-lo. A abordagem é simples, mas tem algumas desvantagens;
- Como o arquivo de contexto é agrupado com o arquivo WAR, precisamos construir e implantar um novo WAR para cada pequena alteração de configuração. O mesmo problema surge se sua aplicação funcionar em um ambiente distribuído ou se sua aplicação precisar ser implantada em diferentes ambientes de teste, como QA, IT, PROD etc.
- O datasource é criado pelo contêiner apenas para uso da aplicação, portanto, não pode ser usado globalmente. Não podemos compartilhar o datasource entre várias aplicações.
- Se houver um datasource global (server.xml) definido com o mesmo nome, o datasource da aplicação será ignorado.
- Contexto do Servidor.xml – Se houver várias aplicações no servidor e você deseja compartilhar um DataSource entre elas, podemos definir isso no arquivo de contexto do servidor.xml. Este arquivo está localizado no diretório
apache-tomcat/conf
. O escopo do arquivo de contexto do servidor é por aplicação, portanto, se você definir um pool de conexões DataSource de 100 conexões e houver 20 aplicações, o DataSource será criado para cada uma delas. Isso resultará em 2000 conexões, o que obviamente consumirá todos os recursos do servidor de banco de dados e prejudicará o desempenho da aplicação. - server.xml e context.xml – Podemos definir o DataSource em nível global ao defini-los no elemento
GlobalNamingResources
do server.xml. Se optarmos por esse método, precisamos definir umResourceLink
no arquivo context.xml do servidor ou especificamente na 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. Quanto à definição do resource link, se deve ser feito no arquivo de contexto do servidor ou no nível da aplicação, depende dos requisitos específicos.
Vamos agora 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 JDBC DataSource.
Exemplo de Configuração do 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 está presente no diretório lib do Tomcat, então, neste caso, o jar jdbc do mysql deve estar presente no 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.
Configuração do Link de Recurso JNDI do DataSource do Tomcat – context.xml
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 JNDI do DataSource do Tomcat
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("Employee ID ");
out.print("Employee Name ");
while(rs.next())
{
out.print("");
out.print("" + rs.getInt("empid") + " ");
out.print("" + rs.getString("name") + " ");
out.print(" ");
}
out.print("
");
//vamos imprimir algumas informações do banco de dados
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 utilizando a configuração baseada em anotações do Servlet 3 e funcionará no Tomcat 7 ou versões superiores. Se estiver utilizando uma versão inferior 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 é;
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. Também poderíamos tê-lo escrito desta forma;
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 resultado abaixo. Isso é tudo para o exemplo de configuração de JNDI do DataSource do Tomcat, você pode definir o recurso de maneira semelhante nos arquivos context.xml também.
Source:
https://www.digitalocean.com/community/tutorials/tomcat-datasource-jndi-example-java