¿Para qué se utiliza WEB-INF en una aplicación web Java EE?

177

Estoy trabajando en una aplicación web Java EE con la siguiente estructura de código fuente:

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

Lo que me interesa es WEB-INF: contiene web.xmlarchivos XML para configurar servlets, contextos de cableado de Spring Beans y etiquetas y vistas JSP.

Estoy tratando de entender qué limita / define esta estructura. Por ejemplo, ¿los archivos JSP siempre deben estar dentro WEB-INFo podrían estar en otro lugar? ¿Y hay algo más que pueda entrar WEB-INF? La entrada de archivos WAR de Wikipedia menciona las classesclases de Java y los libarchivos JAR; no estoy seguro de haber comprendido completamente cuándo serían necesarios, además de las otras ubicaciones de archivos de origen.

Steve Chambers
fuente
1
Esto puede ser útil: gordondickens.com/wordpress/2012/07/03/…
smwikipedia
1
FYI ... Para obtener información sobre cómo se cargan los contenedores de servlets desde WEB-INFy otras ubicaciones, vea la pregunta, Controlar el classpath en un servlet , especialmente esta Respuesta .
Basil Bourque

Respuestas:

216

La especificación Servlet 2.4 dice esto sobre WEB-INF (página 70):

Existe un directorio especial dentro de la jerarquía de la aplicación denominada 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 WEB-INFnodo no forma parte del árbol de documentos públicos de la aplicación . Ningún archivo contenido en el WEB-INFdirectorio puede ser servido directamente a un cliente por el contenedor. Sin embargo, el contenido del WEB-INFdirectorio es visible para el código de servlet usando las llamadas al método getResource y getResourceAsStreamen el ServletContext, y puede exponerse usando las RequestDispatcherllamadas.

Esto significa que los WEB-INFrecursos son accesibles para el cargador de recursos de su aplicación web y no son directamente visibles para el público.

Es por eso que muchos proyectos ponen sus recursos como archivos JSP, JAR / bibliotecas y sus propios archivos de clase o archivos de propiedades o cualquier otra información confidencial en la WEB-INFcarpeta. De lo contrario, serían accesibles utilizando una URL estática simple (útil para cargar CSS o Javascript, por ejemplo).

Sus archivos JSP pueden estar en cualquier lugar desde una perspectiva técnica. Por ejemplo, en Spring puede configurarlos para que estén WEB-INFexplícitamente:

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"
    p:prefix="/WEB-INF/jsp/" 
    p:suffix=".jsp" >
</bean>

Las carpetas WEB-INF/classesy WEB-INF/libmencionadas en el artículo de archivos WAR de Wikipedia son ejemplos de carpetas requeridas por la especificación Servlet en tiempo de ejecución.

Es importante hacer la diferencia entre la estructura de un proyecto y la estructura del archivo WAR resultante.

La estructura del proyecto en algunos casos reflejará parcialmente la estructura del archivo WAR (para recursos estáticos como archivos JSP o archivos HTML y JavaScript, pero este no es siempre el caso.

La transición de la estructura del proyecto al archivo WAR resultante se realiza mediante un proceso de compilación.

Si bien generalmente es libre de diseñar su propio proceso de compilación, hoy en día la mayoría de las personas utilizará un enfoque estandarizado como Apache Maven . Entre otras cosas, Maven define valores predeterminados para qué recursos en 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 proceso de copia simple, en otros casos el proceso de mapeo incluye una transformación, como el filtrado o la compilación y otros.

Un ejemplo : la WEB-INF/classescarpeta contendrá más tarde todas las clases y recursos compilados de Java ( src/main/javay src/main/resources) que el Cargador de clases debe cargar para iniciar la aplicación.

Otro ejemplo : la WEB-INF/libcarpeta contendrá más tarde todos los archivos jar necesarios para la aplicación. En un proyecto de Maven, las dependencias se administran por usted y Maven copia automáticamente los archivos jar necesarios en la WEB-INF/libcarpeta. Eso explica por qué no tienes una libcarpeta en un proyecto maven.

mwhs
fuente
2
El cambio en Servlet 3.0 y 3.1 ( JSR 340 ) permite servir recursos estáticos y JSP desde un JAR almacenado en WEB-INF / lib. Para citar la sección 10.5 de la especificación de Servlet 3.1: Excepto para los recursos estáticos y JSP empaquetados en los recursos META-INF / de un archivo JAR que reside en el directorio WEB-INF / lib, no se pueden incluir otros archivos contenidos en el directorio WEB-INF servido directamente a un cliente por el contenedor. Por lo que la excepción se aplica únicamente a: WAR> WEB-INF> lib> JARarchivo>resources
Albahaca Bourque
1
Vaya, de mi comentario anterior, el cambio esta última frase a: Los archivos estáticos se sirve a partir de: WARarchivo> WEB-INF> lib> JARarchivo> META-INF> resources> yourStaticFilesGoHere .
Basil Bourque
@mwhs Le sugiero que revise su Respuesta con una nueva sección de Servlet 3 y etiquete su contenido actual como una sección de Servlet 2.
Basil Bourque
61

Cuando implementa una aplicación web Java EE (utilizando marcos o no), su estructura debe seguir algunos requisitos / especificaciones. Estas especificaciones provienen de:

  • El contenedor de servlet (p. Ej. Tomcat)
  • API de Java Servlet
  • El dominio de su aplicación
  1. Los requisitos del contenedor de Servlet
    Si utiliza Apache Tomcat, el directorio raíz de su aplicación debe colocarse en la carpeta de la aplicación web. Eso puede ser diferente si usa otro contenedor de servlet o servidor de aplicaciones.

  2. Requisitos de la API de Java Servlet La API de
    Java Servlet establece que el directorio de la aplicación raíz debe tener la siguiente estructura:

    ApplicationName
    |
    |--META-INF
    |--WEB-INF
          |_web.xml       <-- Here is the configuration file of your web app(where you define servlets, filters, listeners...)
          |_classes       <--Here goes all the classes of your webapp, following the package structure you defined. Only 
          |_lib           <--Here goes all the libraries (jars) your application need

Estos requisitos están definidos por la API de Java Servlet.

3. Su dominio de aplicación
Ahora que ha seguido los requisitos del contenedor de Servlet (o servidor de aplicaciones) y los requisitos de la API de Java Servlet, puede organizar las otras partes de su aplicación web en función de lo que necesita.
- Puede colocar sus recursos (archivos JSP, archivos de texto sin formato, archivos de script) en el directorio raíz de su aplicación. Pero entonces, las personas pueden acceder a ellos directamente desde su navegador, en lugar de que sus solicitudes sean procesadas por alguna lógica proporcionada por su aplicación. Por lo tanto, para evitar que se acceda directamente a sus recursos de esa manera, puede colocarlos en el directorio WEB-INF, a cuyo contenido solo puede acceder el servidor.
-Si usa algunos marcos, a menudo usan archivos de configuración. La mayoría de estos marcos (struts, spring, hibernate) requieren que coloque sus archivos de configuración en el classpath (el directorio "clases").

Patrick B.
fuente
12

Debe poner en WEB-INF cualquier página, o parte de página, que no desee que sea pública. Por lo general, JSP o facelets se encuentran fuera de WEB-INF, pero en este caso son fácilmente accesibles para cualquier usuario. En caso de que tenga algunas restricciones de autorización, WEB-INF puede usarse para eso.

WEB-INF / lib puede contener bibliotecas de terceros que no desea empaquetar a nivel del sistema (los JAR pueden estar disponibles para todas las aplicaciones que se ejecutan en su servidor), pero solo para esta aplicación en particular.

En términos generales, muchos archivos de configuraciones también van a WEB-INF.

En cuanto a WEB-INF / classes, existe en cualquier aplicación web, porque esa es la carpeta donde se ubican todas las fuentes compiladas (no JARS, sino archivos .java compilados que usted mismo escribió).

Artem Moskalev
fuente
4

Esta convención se sigue por razones de seguridad. Por ejemplo, si una persona no autorizada puede acceder al archivo JSP raíz directamente desde la URL, puede navegar por toda la aplicación sin autenticación y puede acceder a todos los datos protegidos.


fuente
¿No buscaría el archivo jsp la sesión de una solicitud? Y si no encontrara ninguno, no mostraría algunas partes del sitio.
analizador
3

Existe una convención (no necesaria) de colocar páginas jsp en el directorio WEB-INF para que no se puedan vincular o agregar a marcadores. De esta manera, todas las solicitudes a la página jsp deben dirigirse a través de nuestra aplicación, de modo que se garantice la experiencia del usuario.

Akshay Vijay Jain
fuente