À quoi sert WEB-INF dans une application Web Java EE?

177

Je travaille sur une application Web Java EE avec la structure de code source suivante:

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

Ce qui m'intéresse est WEB-INF- il contient web.xmldes fichiers XML pour la configuration de servlets, des contextes de câblage Spring Bean et des balises et vues JSP.

J'essaie de comprendre ce qui contraint / définit cette structure. Par exemple, les fichiers JSP doivent-ils toujours se trouver à l'intérieur WEB-INFou pourraient-ils être ailleurs? Et y a-t-il autre chose qui pourrait entrer WEB-INF? L' entrée des fichiers WAR de Wikipédia mentionne classesles classes Java et les libfichiers JAR - je ne suis pas sûr d'avoir bien compris quand ils seraient nécessaires en plus des autres emplacements de fichiers source.

Steve Chambers
la source
1
Cela peut être utile: gordondickens.com/wordpress/2012/07/03/…
smwikipedia
1
FYI… Pour en savoir plus sur la manière dont les conteneurs de servlet se chargent depuis WEB-INFet à d'autres emplacements, consultez la question Contrôle du chemin de classe dans un servlet , en particulier cette réponse .
Basil Bourque

Réponses:

216

La spécification Servlet 2.4 dit ceci à propos de WEB-INF (page 70):

Un répertoire spécial existe dans la hiérarchie d'application nommée WEB-INF. Ce répertoire contient toutes les choses liées à l'application qui ne sont pas dans la racine du document de l'application. Le WEB-INFnœud ne fait pas partie de l'arborescence des documents publics de l'application . Aucun fichier contenu dans l' WEB-INFannuaire ne peut être servi directement à un client par le conteneur. Cependant, le contenu du WEB-INFrépertoire est visible par le code de servlet à l'aide des appels de méthode getResource et getResourceAsStreamsur le ServletContext, et peut être exposé à l'aide des RequestDispatcherappels.

Cela signifie que les WEB-INFressources sont accessibles au chargeur de ressources de votre application Web et ne sont pas directement visibles pour le public.

C'est pourquoi de nombreux projets mettent leurs ressources telles que des fichiers JSP, des JAR / bibliothèques et leurs propres fichiers de classe ou fichiers de propriétés ou toute autre information sensible dans le WEB-INFdossier. Sinon, ils seraient accessibles en utilisant une simple URL statique (utile pour charger CSS ou Javascript par exemple).

Vos fichiers JSP peuvent être n'importe où d'un point de vue technique. Par exemple, au printemps, vous pouvez les configurer pour qu'ils soient WEB-INFexplicitement:

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

Les dossiers WEB-INF/classeset WEB-INF/libmentionnés dans l' article sur les fichiers WAR de Wikipédia sont des exemples de dossiers requis par la spécification Servlet au moment de l'exécution.

Il est important de faire la différence entre la structure d'un projet et la structure du fichier WAR résultant.

La structure du projet reflétera dans certains cas partiellement la structure du fichier WAR (pour les ressources statiques telles que les fichiers JSP ou les fichiers HTML et JavaScript, mais ce n'est pas toujours le cas.

La transition de la structure du projet vers le fichier WAR résultant est effectuée par un processus de construction.

Alors que vous êtes généralement libre de concevoir votre propre processus de construction, de nos jours, la plupart des gens utiliseront une approche standardisée telle qu'Apache Maven . Entre autres choses, Maven définit les valeurs par défaut pour lesquelles les ressources de la structure du projet correspondent aux ressources de l'artefact résultant (l'artefact résultant est le fichier WAR dans ce cas). Dans certains cas, le mappage consiste en un processus de copie simple, dans d'autres cas, le processus de mappage comprend une transformation, telle que le filtrage ou la compilation et d'autres.

Un exemple : le WEB-INF/classesdossier contiendra plus tard toutes les classes et ressources java compilées ( src/main/javaet src/main/resources) qui doivent être chargées par le Classloader pour démarrer l'application.

Autre exemple : le WEB-INF/libdossier contiendra plus tard tous les fichiers jar nécessaires à l'application. Dans un projet maven, les dépendances sont gérées pour vous et maven copie automatiquement les fichiers jar nécessaires dans le WEB-INF/libdossier pour vous. Cela explique pourquoi vous n'avez pas de libdossier dans un projet maven.

mwhs
la source
2
Le changement de Servlet 3.0 et 3.1 ( JSR 340 ) permet de servir des ressources statiques et des JSP à partir d'un JAR stocké dans WEB-INF / lib. Pour citer la section 10.5 de la spécification Servlet 3.1: À l'exception des ressources statiques et des JSP conditionnées dans le META-INF / resources d'un fichier JAR qui réside dans le répertoire WEB-INF / lib, aucun autre fichier contenu dans le répertoire WEB-INF ne peut être servi directement à un client par le conteneur. Ainsi , l'exception applique uniquement à: WAR> WEB-INF> lib> JARfichier>resources
Bourque Basil
1
Whoops, de mon commentaire ci - dessus, changement dernière phrase: Les fichiers statiques peut être servi à partir de : WARFichier> WEB-INF> lib> JARFichier> META-INF> resources> yourStaticFilesGoHere .
Basil Bourque
@mwhs Je vous suggère de réviser votre réponse avec une nouvelle section Servlet 3 et d'étiqueter votre contenu actuel en tant que section Servlet 2.
Basil Bourque
61

Lorsque vous déployez une application Web Java EE (à l'aide de frameworks ou non), sa structure doit respecter certaines exigences / spécifications. Ces spécifications proviennent:

  • Le conteneur de servlet (par exemple Tomcat)
  • API Java Servlet
  • Votre domaine d'application
  1. Les exigences du conteneur Servlet
    Si vous utilisez Apache Tomcat, le répertoire racine de votre application doit être placé dans le dossier webapp. Cela peut être différent si vous utilisez un autre conteneur de servlet ou serveur d'applications.

  2. Configuration requise pour l'API Java Servlet L'API
    Java Servlet indique que votre répertoire d'application racine doit avoir la structure suivante:

    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

Ces exigences sont définies par l'API Java Servlet.

3. Votre domaine d'application
Maintenant que vous avez suivi les exigences du conteneur Servlet (ou du serveur d'application) et les exigences de l'API Java Servlet, vous pouvez organiser les autres parties de votre application Web en fonction de vos besoins.
- Vous pouvez placer vos ressources (fichiers JSP, fichiers texte brut, fichiers script) dans le répertoire racine de votre application. Mais alors, les gens peuvent y accéder directement depuis leur navigateur, au lieu que leurs demandes soient traitées par une logique fournie par votre application. Ainsi, pour éviter que vos ressources ne soient directement accédées comme ça, vous pouvez les mettre dans le répertoire WEB-INF, dont le contenu n'est accessible que par le serveur.
-Si vous utilisez certains frameworks, ils utilisent souvent des fichiers de configuration. La plupart de ces frameworks (struts, spring, hibernate) nécessitent que vous mettiez leurs fichiers de configuration dans le classpath (le répertoire "classes").

Patrick B.
la source
12

Vous devez mettre dans WEB-INF toutes les pages ou parties de pages que vous ne souhaitez pas rendre publiques. Habituellement, JSP ou facelets se trouvent en dehors de WEB-INF, mais dans ce cas, ils sont facilement accessibles pour tout utilisateur. Dans le cas où vous avez des restrictions d'autorisation, WEB-INF peut être utilisé pour cela.

WEB-INF / lib peut contenir des bibliothèques tierces que vous ne souhaitez pas empaqueter au niveau du système (les JAR peuvent être disponibles pour toutes les applications exécutées sur votre serveur), mais uniquement pour cette application particulière.

De manière générale, de nombreux fichiers de configuration vont également dans WEB-INF.

Quant à WEB-INF / classes - il existe dans n'importe quelle application Web, car c'est le dossier où toutes les sources compilées sont placées (pas JARS, mais les fichiers .java compilés que vous avez écrits vous-même).

Artem Moskalev
la source
4

Cette convention est suivie pour des raisons de sécurité. Par exemple, si une personne non autorisée est autorisée à accéder au fichier JSP racine directement à partir de l'URL, elle peut naviguer dans toute l'application sans aucune authentification et accéder à toutes les données sécurisées.


la source
Le fichier jsp ne chercherait-il pas toujours la session d'une requête? Et s'il n'en trouvait pas, il n'afficherait pas certaines parties du site.
parsecer le
3

Il existe une convention (pas nécessaire) de placer les pages jsp sous le répertoire WEB-INF afin qu'elles ne puissent pas être liées ou mises en signet. De cette façon, toutes les demandes à la page jsp doivent être dirigées via notre application, afin que l'expérience utilisateur soit garantie.

Akshay Vijay Jain
la source