Saltar al contenido

Externalizar la configuración de la aplicación web de Tomcat desde el archivo .war

Solución:

Tu tomcat/conf/Catalina/<host> puede contener descriptores de contexto que le permiten configurar muchas cosas, incluida la definición de “entradas de entorno”, a las que se puede acceder desde Java a través de JNDI. Hay muchas formas de utilizarlo. Personalmente, configuro una entrada de entorno que es la ruta del sistema de archivos a mi archivo de propiedades. Mi aplicación está diseñada para verificar esta entrada y, si no existe, busque el archivo en la ruta de clase. De esa manera, en dev, tenemos las propiedades de desarrollo allí mismo en la ruta de clases, pero cuando compilamos e implementamos, lo apuntamos a un archivo externo.

Hay buena documentación para configurar un contexto en el sitio web de Tomcat. Ver el Definiendo un contexto sección sobre detalles sobre cómo crear el archivo y dónde colocarlo.

Por ejemplo, si su host se llama myHost y tu aplicación es un archivo war llamado myApp.war en el webapps directorio, entonces podría crear tomcat/conf/Catalina/myHost/myApp.xml con este contenido:

<Context>
    <Environment name="configurationPath" value="/home/tomcat/myApp.properties" type="java.lang.String"/>
</Context>

Luego, desde su código, haría una búsqueda JNDI en java:comp/env/configurationPath (95% de certeza aquí) para obtener ese valor de cadena.

me gusta .properties archivos en lugar de

  • JNDI – por qué construir un objeto complejo durante la configuración del programa en lugar del tiempo de inicialización?
  • propiedades del sistema: no puede configurar por separado varias instancias del mismo WAR en un solo Tomcat
  • Parámetros de contexto: solo son accesibles en javax.servlet.Filter, javax.servlet.ServletContextListener lo cual puede ser un inconveniente

Tomcat 7 Contexto contiene el elemento Loader. Según el descriptor de implementación de documentos (qué en <Context> etiqueta) se puede colocar en:

  • $CATALINA_BASE/conf/server.xml – malo: requiere reiniciar el servidor para volver a leer la configuración
  • $CATALINA_BASE/conf/context.xml – malo – compartido en todas las aplicaciones
  • $CATALINA_BASE/work/$APP.war:/META-INF/context.xml – malo – requiere reempaquetado para cambiar la configuración
  • $CATALINA_BASE/work/[enginename]/[hostname]/$APP/META-INF/context.xmlbonito, pero mira la última opción !!
  • $CATALINA_BASE/webapps/$APP/META-INF/context.xmlbonito, pero mira la última opción !!
  • $CATALINA_BASE/conf/[enginename]/[hostname]/$APP.xmlmejor – ¡completamente fuera de la aplicación y se escaneó automáticamente en busca de cambios!

Context puede contener personalizado Loader org.apache.catalina.loader.VirtualWebappLoader (disponible en Tomcat 7 moderno, puede agregar propia ruta de clases separada para usted .properties), y Parameter (se accede a través de FilterConfig.getServletContext().getInitParameter(name)) y Environment (se accede a través de new InitialContext().lookup("java:comp/env").lookup("name")):

<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>

Si usa Spring y su configuración XML:

<context:property-placeholder location="classpath:app.properties"/>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
    <property name="url" value="jdbc:oracle:thin:@${db.host}:${db.port}:${db.user}"/>
    <property name="username" value="${db.user}"/>
    <property name="password" value="${db.pass}"/>
</bean>

Con Spring, inyectar las propiedades anteriores en los campos de frijoles es fácil:

@Value("${db.user}") String defaultSchema;

en lugar de JNDI:

@Inject ApplicationContext context;
Enviroment env = context.getEnvironment();
String defaultSchema = env.getProperty("db.user");

Tenga en cuenta también que EL permite esto (valores predeterminados y sustitución recursiva profunda):

@Value('${db.user:testdb}') private String dbUserName;

<property name="username" value="${db.user.${env}}"/>

Ver también:

  • Agregar un directorio a la ruta de clases de tomcat
  • ¿Puedo crear una ruta de clase personalizada por aplicación en Tomcat?
  • Cómo leer un archivo de propiedades fuera de mi contexto de aplicación web en Tomcat
  • Configure Tomcat para usar el archivo de propiedades para cargar información de conexión de base de datos
  • ¿Debería configurar las propiedades de conexión de la base de datos en server.xml o context.xml?
  • Externalizar la configuración de Tomcat

NOTA Con la extensión de classpath al directorio en vivo, también permitido externilizar cualquier otra configuración, como registro, autenticación, atc. Yo externilizo logback.xmlDe tal manera.

ACTUALIZAR Tomcat 8 cambia la sintaxis para <Resources> y <Loader> elementos, 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>
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *