Estoy trabajando en una aplicación web Java EE con la siguiente estructura de código fuente:
lenguaje: lang-none -->
src/main/java <-- multiple packages containing java classes
src/test/java <-- multiple packages containing JUnit tests
src/main/resources <-- includes properties files for textual messages
src/main/webapp/resources <-- includes CSS, images and all Javascript files
src/main/webapp/WEB-INF
src/main/webapp/WEB-INF/tags
src/main/webapp/WEB-INF/views
La parte que me interesa es WEB-INF
- contiene web.xml
, archivos XML para configurar servlets, contextos de cableado de beans de Spring y etiquetas y vistas JSP.
Intento entender qué limita/define esta estructura. Por ejemplo, ¿los archivos JSP tienen que estar siempre dentro de WEB-INF
o pueden estar en otro lugar? ¿Y hay algo más que pueda ir en WEB-INF
? La entrada de Wikipedia WAR files menciona classes
para las clases Java y lib
para los archivos JAR - no estoy seguro de que haya comprendido bien cuándo se necesitan además de las otras ubicaciones de los archivos fuente.
La especificación Servlet 2.4 dice esto sobre el WEB-INF (página 70):
Existe un directorio especial dentro de la jerarquía de la aplicación llamado
WEB-INF
. Este directorio contiene todas las cosas relacionadas con la aplicación que no están en la raíz del documento de la aplicación. El directorioWEB-INF
no forma parte del árbol de documentos públicos de la aplicación. Ningún archivo contenido en el directorioWEB-INF
puede ser servido directamente a un cliente por el contenedor. Sin embargo, el contenido del directorio WEB-INFson visibles para el código de los servlets usando las funciones
getResource ygetResourceAsStream
en elServletContext
, y pueden ser expuestos usando las llamadas aRequestDispatcher
.
Esto significa que los recursos WEB-INF
son accesibles para el cargador de recursos de tu aplicación web y no son directamente visibles para el público.
Esta es la razón por la que muchos proyectos ponen sus recursos como archivos JSP, JARs/librerías y sus propios archivos de clase o archivos de propiedades o cualquier otra información sensible en la carpeta WEB-INF
. De lo contrario, serían accesibles mediante una simple URL estática (útil para cargar CSS o Javascript, por ejemplo).
Sin embargo, desde el punto de vista técnico, los archivos JSP pueden estar en cualquier lugar. Por ejemplo, en Spring puedes configurarlos para que estén en WEB-INF
explícitamente:
lenguaje: xml -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" >
</bean>
Las carpetas WEB-INF/classes
y WEB-INF/lib
mencionadas en el artículo de Wikipedia's WAR files son ejemplos de carpetas requeridas por la especificación Servlet en tiempo de ejecución.
Es importante diferenciar entre la estructura de un proyecto y la estructura del archivo WAR resultante.
La estructura del proyecto reflejará en algunos casos parcialmente la estructura del fichero WAR (para recursos estáticos como ficheros JSP o ficheros HTML y JavaScript, pero no siempre es así.
***La transición de la estructura del proyecto al archivo WAR resultante se realiza mediante un proceso de compilación.
Aunque normalmente eres libre de diseñar tu propio proceso de construcción, hoy en día la mayoría de la gente utiliza un enfoque estandarizado como Apache Maven. Entre otras cosas, Maven define por defecto qué recursos de la estructura del proyecto se asignan a qué recursos en el artefacto resultante (el artefacto resultante es el archivo WAR en este caso). En algunos casos el mapeo consiste en un simple proceso de copia en otros casos el proceso de mapeo incluye una transformación, como filtrado o compilación y otros.
Un ejemplo: La carpeta WEB-INF/classes
contendrá posteriormente todas las clases y recursos java compilados (src/main/java
y src/main/resources
) que deben ser cargados por el cargador de clases para iniciar la aplicación.
*Otro ejemplo: La carpeta WEB-INF/lib
contendrá posteriormente todos los archivos jar necesarios para la aplicación. En un proyecto maven las dependencias se gestionan por ti y maven automáticamente copia los archivos jar necesarios a la carpeta WEB-INF/lib
por ti. Eso explica por qué no tienes una carpeta lib
en un proyecto maven.
Cuando se despliega una aplicación web Java EE (utilizando frameworks o no), su estructura debe seguir algunos requisitos/especificaciones. Estas especificaciones provienen de :
El contenedor de servlets (por ejemplo, Tomcat)
Los requisitos del contenedor de servlets
Si usas Apache Tomcat, el directorio raíz de tu aplicación debe colocarse en la carpeta webapp. Esto puede ser diferente si usas otro contenedor de servlets o servidor de aplicaciones
;
Requisitos de la API de Java Servlet
La API de Java Servlet establece que el directorio raíz de su aplicación debe tener la siguiente estructura:
ApplicationName
|
|--META-INF
|--WEB-INF
|_web.xml <-- Aquí va el fichero de configuración de tu webapp(donde defines servlets, filtros, listeners...)
|_classes <--Aquí van todas las clases de tu webapp, siguiendo la estructura de paquetes que definiste. Sólo
|_lib <--Aquí van todas las librerías (jars) que necesita tu aplicación
Estos requisitos están definidos por la API de Java Servlet;
3. El dominio de tu aplicación
Ahora que has seguido los requisitos del contenedor de Servlets (o servidor de aplicaciones) y los requisitos de la API de Java Servlet, puedes organizar las otras partes de tu webapp en función de lo que necesites.
- Puedes poner tus recursos (archivos JSP, archivos de texto plano, archivos de script) en el directorio raíz de tu aplicación. Pero entonces, la gente puede acceder a ellos directamente desde su navegador, en lugar de que sus peticiones sean procesadas por alguna lógica proporcionada por tu aplicación. Así que, para evitar que tus recursos sean accedidos directamente de esa manera, puedes ponerlos en el directorio WEB-INF, cuyo contenido sólo es accesible por el servidor.
-Si utilizas algunos frameworks, éstos suelen utilizar archivos de configuración. La mayoría de estos frameworks (struts, spring, hibernate) requieren que pongas sus archivos de configuración en el classpath (el directorio "classes").
Debes poner en WEB-INF cualquier página, o trozo de página, que no quieras que sea pública. Normalmente, las JSP o facelets se encuentran fuera de WEB-INF, pero en este caso son fácilmente accesibles para cualquier usuario. En caso de tener algunas restricciones de autorización, WEB-INF puede ser utilizado para eso.
WEB-INF/lib puede contener librerías de terceros que no quieras empaquetar a nivel de sistema (los JARs pueden estar disponibles para todas las aplicaciones que se ejecuten en tu servidor), pero sólo para esta aplicación en particular.
En general, muchos archivos de configuración también van en WEB-INF.
En cuanto a WEB-INF/classes - existe en cualquier web-app, porque esa es la carpeta donde se colocan todas las fuentes compiladas (no JARS, sino archivos .java compilados que escribiste tú mismo).