Saltar al contenido

¿Dónde colocar y cómo leer los archivos de recursos de configuración en una aplicación basada en servlets?

Solución:

Es tu elección. Básicamente, hay tres formas en un archivo de aplicación web Java (WAR):


1. Ponlo en classpath

Para que puedas cargarlo por ClassLoader#getResourceAsStream() con una ruta relativa a classpath:

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("foo.properties");
// ...
Properties properties = new Properties();
properties.load(input);

Aquí foo.properties se supone que debe colocarse en una de las raíces que están cubiertas por la ruta de clases predeterminada de una aplicación web, por ejemplo, la aplicación web /WEB-INF/lib y /WEB-INF/classes, del servidor /lib, o JDK / JRE’s /lib. Si el archivo de propiedades es específico de la aplicación web, lo mejor es colocarlo en /WEB-INF/classes. Si está desarrollando un proyecto WAR estándar en un IDE, colóquelo src carpeta (la carpeta de origen del proyecto). Si está utilizando un proyecto de Maven, colóquelo /main/resources carpeta.

Alternativamente, también puede colocarlo en algún lugar fuera de la ruta de clases predeterminada y agregar su ruta a la ruta de clases del servidor de aplicaciones. En, por ejemplo, Tomcat puede configurarlo como shared.loader propiedad de Tomcat/conf/catalina.properties.

Si ha colocado el foo.properties en una estructura de paquete Java como com.example, entonces necesitas cargarlo como se muestra a continuación

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("com/example/foo.properties");
// ...

Tenga en cuenta que esta ruta de un cargador de clases de contexto no debe comenzar con un /. Solo cuando utiliza un cargador de clases “relativo” como SomeClass.class.getClassLoader(), entonces necesitas comenzar con un /.

ClassLoader classLoader = getClass().getClassLoader();
InputStream input = classLoader.getResourceAsStream("/com/example/foo.properties");
// ...

Sin embargo, la visibilidad del archivo de propiedades depende del cargador de clases en cuestión. Solo es visible para el mismo cargador de clases que el que cargó la clase. Por lo tanto, si la clase se carga, por ejemplo, mediante el cargador de clases común del servidor en lugar del cargador de clases de la aplicación web, y el archivo de propiedades está dentro de la aplicación web, entonces es invisible. El cargador de clases de contexto es su apuesta más segura, por lo que puede colocar el archivo de propiedades “en todas partes” en la ruta de clases y / o desea poder anular uno proporcionado por el servidor desde la aplicación web.


2. Ponlo en contenido web

Para que puedas cargarlo por ServletContext#getResourceAsStream() con una ruta relativa al contenido web:

InputStream input = getServletContext().getResourceAsStream("/WEB-INF/foo.properties");
// ...

Tenga en cuenta que he demostrado colocar el archivo en /WEB-INF carpeta, de lo contrario habría sido públicamente accesible para cualquier navegador web. También tenga en cuenta que el ServletContext está en cualquier HttpServlet clase simplemente accesible por el heredado GenericServlet#getServletContext() y en Filter por FilterConfig#getServletContext(). En caso de que no esté en una clase de servlet, generalmente es solo inyectable a través de @Inject.


3. Ponlo en el sistema de archivos del disco local.

Para que puedas cargarlo de la forma habitual java.io manera con una ruta absoluta del sistema de archivos del disco local:

InputStream input = new FileInputStream("/absolute/path/to/foo.properties");
// ...

Tenga en cuenta la importancia de utilizar una ruta absoluta. Las rutas relativas del sistema de archivos del disco local son absolutamente prohibidas en una aplicación web Java EE. Consulte también el primer enlace “Ver también” a continuación.


Cual elegir?

Solo sopese las ventajas / desventajas en tu propia opinión de mantenibilidad.

Si los archivos de propiedades son “estáticos” y nunca es necesario cambiarlos durante el tiempo de ejecución, puede mantenerlos en WAR.

Si prefiere poder editar archivos de propiedades desde fuera de la aplicación web sin la necesidad de reconstruir y volver a implementar el WAR cada vez, colóquelo en la ruta de clases fuera del proyecto (si es necesario, agregue el directorio a la ruta de clases).

Si prefiere poder editar archivos de propiedades mediante programación desde dentro de la aplicación web usando Properties#store() método, colóquelo fuera de la aplicación web. Como el Properties#store() requiere un Writer, no puede utilizar una ruta del sistema de archivos de disco. Esa ruta, a su vez, puede pasarse a la aplicación web como un argumento de VM o propiedad del sistema. Como precaucion, Nunca usar getRealPath(). Todos los cambios en la carpeta de implementación se perderán en una nueva implementación por la sencilla razón de que los cambios no se reflejan en el archivo WAR original.

Ver también:

  • getResourceAsStream () frente a FileInputStream
  • Agregar un directorio a la ruta de clases de tomcat
  • Acceder al archivo de propiedades en una aplicación JSF mediante programación

Advertencia: si coloca archivos de configuración en su WEB-INF/classes carpeta, y su IDE, digamos Eclipse, hace una limpieza / reconstrucción, destruirá sus archivos conf a menos que estén en el directorio fuente de Java. La gran respuesta de BalusC alude a eso en la opción 1, pero quería agregar énfasis.

Aprendí por las malas que si “copia” un proyecto web en Eclipse, lo limpia / reconstruye desde cualquier carpeta de origen. En mi caso, había agregado un “directorio de origen vinculado” de nuestra biblioteca de Java POJO, se compilaría en el WEB-INF/classes carpeta. Hacer una limpieza / reconstrucción en ese proyecto (no en el proyecto de la aplicación web) causó el mismo problema.

Pensé en poner mis confs en la carpeta POJO src, pero estas confs son todas para bibliotecas de terceros (como Quartz o URLRewrite) que están en el WEB-INF/lib carpeta, por lo que no tenía sentido. Planeo probar ponerlo en la carpeta de proyectos web “src” cuando llegue a él, pero esa carpeta está actualmente vacía y tener archivos conf parece poco elegante.

Así que voto por poner archivos conf en WEB-INF/commonConfFolder/filename.properties, Siguiente a la carpeta de clases, que es la opción 2 de Balus.

Ej .: en el archivo web.xml la etiqueta

<context-param>
        <param-name>chatpropertyfile</param-name>
        <!--  Name of the chat properties file. It contains the name and description                   of rooms.-->     
        <param-value>chat.properties</param-value>
    </context-param>

Y chat.properties puede declarar sus propiedades así

Por ejemplo:

Jsp = Discussion about JSP can be made here.
Java = Talk about java and related technologies like J2EE.
ASP = Discuss about Active Server Pages related technologies like VBScript and JScript etc.
Web_Designing = Any discussion related to HTML, JavaScript, DHTML etc.
StartUp = Startup chat room. Chatter is added to this after he logs in.
¡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 *