Bienvenido al Tutorial de Ejemplo de Tomcat DataSource JNDI. En el último tutorial, examinamos el DataSource JDBC y aprendimos cómo utilizarlo en una aplicación Java independiente.
Tomcat DataSource JNDI
El beneficio real de DataSource se obtiene cuando lo utilizamos con un Contexto JNDI. Por ejemplo, el grupo de conexiones en una aplicación web desplegada en un contenedor de servlets. La mayoría de los contenedores de servlets populares proporcionan soporte integrado para DataSource a través de la configuración de recursos y el contexto JNDI. Esto nos ayuda a crear y utilizar un grupo de conexiones DataSource con solo unas pocas líneas de configuración. Este tutorial tiene como objetivo proporcionar un ejemplo de configuración de Tomcat DataSource JNDI. Apache Tomcat proporciona tres formas de configurar DataSource en el contexto JNDI.
- Archivo context.xml – Esta es la forma más fácil de configurar DataSource, todo lo que necesitamos es un archivo context.xml en el directorio META-INF. Debemos definir el elemento Resource en el archivo de contexto y el contenedor se encargará de cargarlo y configurarlo. El enfoque es simple pero tiene algunos inconvenientes;
- Dado que el archivo de contexto está incluido en el archivo WAR, necesitamos construir y desplegar un nuevo WAR por cada cambio de configuración pequeño. El mismo problema surge si su aplicación funciona en un entorno distribuido o si su aplicación necesita ser desplegada en diferentes entornos de prueba como QA, IT, PROD, etc.
- El datasource es creado por el contenedor solo para el uso de la aplicación, por lo que no se puede utilizar globalmente. No podemos compartir el datasource entre múltiples aplicaciones.
- Si hay un datasource global (server.xml) definido con el mismo nombre, se ignora el datasource de la aplicación.
- Contexto del servidor.xml – Si hay múltiples aplicaciones en el servidor y desea compartir DataSource entre ellas, podemos definirlo en el archivo context.xml del servidor. Este archivo se encuentra en el directorio
apache-tomcat/conf
. El alcance del archivo context.xml del servidor es por aplicación, por lo que si define un pool de conexiones DataSource de 100 conexiones y hay 20 aplicaciones, entonces el DataSource se creará para cada una de las aplicaciones. Esto resultará en 2000 conexiones que obviamente consumirán todos los recursos del servidor de base de datos y afectarán el rendimiento de la aplicación. - server.xml y context.xml – Podemos definir DataSource a nivel global al definirlos en el elemento
GlobalNamingResources
del server.xml. Si usamos este enfoque, entonces necesitamos definir unResourceLink
desde el archivo context.xml del servidor o específico de la aplicación. Esta es la forma preferida cuando se busca compartir un pool de recursos común entre múltiples aplicaciones que se ejecutan en el servidor. En cuanto al enlace de recursos, si definirlo a nivel de servidor en el archivo xml de contexto o a nivel de aplicación depende de su requisito.
Veamos el ejemplo de JNDI DataSource de Tomcat en una aplicación web Java. Para la configuración de datos de prueba, consulte mi último artículo sobre Ejemplo de DataSource JDBC.
Ejemplo de Configuración JNDI de Tomcat DataSource – server.xml
Agrega el siguiente código en el archivo server.xml de Tomcat. El código debe ser añadido dentro del elemento GlobalNamingResources
. Asegúrate también de que el controlador de la base de datos esté presente en el directorio lib de Tomcat; en este caso, el archivo jar de MySQL JDBC debe estar presente en la librería de 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"/>
Aquí estamos creando un contexto JNDI con el nombre jdbc/MyDB
, que es un tipo de DataSource. Pasamos las configuraciones de la base de datos en los atributos url, username, password y driverClassName. Las propiedades de pooling de conexiones están definidas en los atributos maxActive, maxIdle y minIdle.
Configuración de Enlace de Recurso JNDI de Tomcat DataSource – context.xml
Agrega el siguiente código en el archivo context.xml del servidor.
<ResourceLink name="jdbc/MyLocalDB"
global="jdbc/MyDB"
auth="Container"
type="javax.sql.DataSource" />
Observa que el nombre del enlace de recurso es diferente al enlace global; debemos usar este nombre en nuestro programa Java para obtener el DataSource.
Ejemplo de JNDI de DataSource de Tomcat
Crea una aplicación web dinámica con el nombre JDBCDataSourceTomcat y luego crea un Servlet con el siguiente código.
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 a imprimir alguna información de la base de datos
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");
}
}
}
}
Observa que estoy utilizando la configuración basada en anotaciones de Servlet 3 y funcionará en Tomcat 7 o versiones superiores. Si estás utilizando una versión más baja de Tomcat, entonces necesitas hacer algunas modificaciones en el código del servlet para eliminar la anotación WebServlet y configurarla en el archivo web.xml. La parte del código del servlet en la que estamos interesados es;
ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("java:/comp/env/jdbc/MyLocalDB");
Esta es la forma de obtener los recursos JNDI definidos para ser utilizados por la aplicación. También podríamos haberlo escrito de esta manera;
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"/>
Y cuando reiniciamos el servidor y ejecutamos la aplicación, se conectará a la base de datos de Oracle y producirá el siguiente resultado. Eso es todo para el ejemplo de configuración de JNDI de DataSource de Tomcat, también puedes definir el recurso de manera similar en archivos context.xml.
Source:
https://www.digitalocean.com/community/tutorials/tomcat-datasource-jndi-example-java