traduccion - Externalizar la configuración de Tomcat
tomcat truss (4)
Tengo una configuración de DataSource en context.xml. ¿Es posible no codificar los parámetros de la base de datos en ese archivo? Por ejemplo, ¿usar un archivo de propiedades externo y cargar los parámetros desde él?
Algo como esto:
context.xml:
<Resource
name="jdbc/myDS" auth="Container"
type="javax.sql.DataSource"
driverClassName="oracle.jdbc.OracleDriver"
url="${db.url}"
username="${db.user}"
password="${db.pwd}"
maxActive="2"
maxIdle="2"
maxWait="-1"/>
db.properties:
db.url=jdbc:oracle:thin:@server:1521:sid
db.user=test
db.pwd=test
Claro, esto es posible. ServletContextListener registrar ServletContextListener en su web.xml
esta manera:
<!-- at the beginning of web.xml -->
<listener>
<listener-class>com.mycompany.servlets.ApplicationListener</listener-class>
</listener>
Fuente de com.mycompany.servlets.ApplicationListener
:
package com.mycompany.servlets;
public class ApplicationListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
// this method is invoked once when web-application is deployed (started)
// reading properties file
FileInputStream fis = null;
Properties properties = new Properties();
try {
fis = new FileInputStream("path/to/db.properties")
properties.load(fis);
} catch(IOException ex) {
throw new RuntimeException(ex);
} finally {
try {
if(fis != null) {
fis.close();
}
} catch(IOException e) {
throw new RuntimeException(e);
}
}
// creating data source instance
SomeDataSourceImpl dataSource = new SomeDataSourceImpl();
dataSource.setJdbcUrl(properties.getProperty("db.url"));
dataSource.setUser(properties.getProperty("db.user"));
dataSource.setPassword(properties.getProperty("db.pwd"));
// storing reference to dataSource in ServletContext attributes map
// there is only one instance of ServletContext per web-application, which can be accessed from almost anywhere in web application(servlets, filters, listeners etc)
final ServletContext servletContext = servletContextEvent.getServletContext();
servletContext.setAttribute("some-data-source-alias", dataSource);
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
// this method is invoked once when web-application is undeployed (stopped) - here one can (should) implement resource cleanup etc
}
}
Y luego, en algún lugar del código de la aplicación web para acceder a dataSource
:
ServletContext servletContext = ...; // as mentioned above, it should be accessible from almost anywhere
DataSource dataSource = (DataSource) servletContext.getAttribute("some-data-source-alias");
// use dataSource
SomeDataSourceImpl
es una implementación concreta de javax.sql.DataSource . Por favor, avise si no usa un DataSource
específico (como ComboPooledDataSource para la agrupación de conexiones) y no sabe cómo obtenerlo. Publicaré cómo evitarlo.
some-data-source-alias
- es solo String
alias (key) para su instancia de DataSource
en el mapa de atributos ServletContext
. Una buena práctica es dar alias precedidos con el nombre del paquete como com.mycompany.mywebapp.dataSource
.
Espero que esto ayude...
Como se indica here , puede hacer esto de la siguiente manera.
1.Descargue la biblioteca tomcat para obtener la definición de la interfaz, por ejemplo, definiendo la dependencia de maven:
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-coyote</artifactId>
<version>7.0.47</version>
</dependency>
2. El siguiente paso es crear un com.mycompany.MyPropertyDecoder de la siguiente manera:
import org.apache.tomcat.util.IntrospectionUtils;
public class MyPropertyDecoder implements IntrospectionUtils.PropertySource {
@Override
public String getProperty(String arg0) {
//TODO read properties here
return null;
}
}
3.Ponga MyPropertyDecoder.class en la carpeta tomcat7 / lib
4.Defina org.apache.tomcat.util.digester. Propiedad PROPERTY_SOURCE en tomcat7 / conf / catalina.properties de la siguiente manera:
org.apache.tomcat.util.digester.PROPERTY_SOURCE=com.mycompany.MyPropertyDecoder
5. Actualice su context.xml con propiedades vars
<Resource name="jdbc/TestDB"
auth="Container"
type="javax.sql.DataSource"
username="root"
password="${db.password}"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/mysql?autoReconnect=true"
...
6. Coloque el archivo application.properties en algún lugar de su proyecto / contenedor
7. Asegúrese de que MyPropertyDecoder lee correctamente application.properties
8. ¡Disfruta!
PS También hay un enfoque similar descrito para tc Server .
Es fácil con los descriptores de despliegue de contexto , que parecen:
<Context docBase="${basedir}/src/main/webapp"
reloadable="true">
<!-- http://tomcat.apache.org/tomcat-7.0-doc/config/context.html -->
<Resources className="org.apache.naming.resources.VirtualDirContext"
extraResourcePaths="/WEB-INF/classes=${basedir}/target/classes,/WEB-INF/lib=${basedir}/target/${project.build.finalName}/WEB-INF/lib"/>
<Loader className="org.apache.catalina.loader.VirtualWebappLoader"
virtualClasspath="${basedir}/target/classes;${basedir}/target/${project.build.finalName}/WEB-INF/lib"/>
<JarScanner scanAllDirectories="true"/>
<Parameter name="min" value="dev"/>
<Environment name="app.devel.ldap" value="USER" type="java.lang.String" override="true"/>
<Environment name="app.devel.permitAll" value="true" type="java.lang.String" override="true"/>
</Context>
Hay varios lugares donde puede poner esta configuración, en mi opinión, la mejor opción es $CATALINA_BASE/conf/[enginename]/[hostname]/$APP.xml
En el Context
XML anterior se puede incluir el Loader
personalizado org.apache.catalina.loader.VirtualWebappLoader (disponible en Tomcat 7 moderno, puede agregar su propia ruta de clase por aplicación a sus archivos .properties
), Parameter
(accesible a través de FilterConfig.getServletContext().getInitParameter(name)
) y Environment
(se accede a través de un new InitialContext().lookup("java:comp/env").lookup("name")
)
Ver discusión en:
- Agregando un directorio a Tomcat Classpath
- ¿Puedo crear un classpath personalizado por aplicación en Tomcat?
- Cómo leer un archivo de propiedades fuera del contexto de mi aplicación web en Tomcat
- Configure Tomcat para usar el archivo de propiedades para cargar información de conexión de base de datos
- Debe configurar las propiedades de conexión de la base de datos en server.xml o context.xml
ACTUALIZA la sintaxis de cambio de Tomcat 8 para los elementos <Resources>
y <Loader>
, la parte correspondiente ahora se ve así:
<Resources>
<PostResources className="org.apache.catalina.webresources.DirResourceSet"
webAppMount="/WEB-INF/classes" base="${basedir}/target/classes" />
<PostResources className="org.apache.catalina.webresources.DirResourceSet"
webAppMount="/WEB-INF/lib" base="${basedir}/target/${project.build.finalName}/WEB-INF/lib" />
</Resources>
Si este es Tomcat 7, puede escribir sus propias variables de lectura org.apache.tomcat.util.IntrospectionUtils.PropertySource
escritas como "$ {...}" en context.xml
. Deberá establecer la propiedad del sistema org.apache.tomcat.util.digester.PROPERTY_SOURCE
para que apunte a su implementación de PropertySource
.