230 votes

Où placer et comment lire les fichiers de ressources de configuration dans une application basée sur des servlets ?

Dans mon application web, je dois envoyer des courriels à un ensemble d'utilisateurs prédéfinis, par exemple finance@xyz.com Je souhaite donc l'ajouter à un .properties et y accéder en cas de besoin. Est-ce une procédure correcte ? Si oui, où dois-je placer ce fichier ? J'utilise Netbeans IDE qui a deux dossiers séparés pour les fichiers source et JSP.

0 votes

JNDI pourrait peut-être être une solution ?

475voto

BalusC Points 498232

C'est votre choix. Il y a essentiellement trois façons de procéder dans une archive d'application web Java (WAR) :


1. Mettez-le dans le classpath

Pour que vous puissiez le charger en ClassLoader#getResourceAsStream() avec un chemin relatif à la classe :

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

Ici foo.properties est censé être placé dans l'une des racines couvertes par le classpath par défaut d'une webapp, par exemple le répertoire /WEB-INF/lib y /WEB-INF/classes le serveur /lib ou les JDK/JRE /lib . Si le fichier de propriétés est spécifique à la webapp, le mieux est de le placer dans le répertoire /WEB-INF/classes . Si vous développez un projet WAR standard dans un IDE, déposez-le dans l'onglet src (le dossier source du projet). Si vous utilisez un projet Maven, déposez-le dans le dossier /main/resources carpeta.

Vous pouvez également le placer quelque part en dehors du classpath par défaut et ajouter son chemin au classpath de l'appserver. Dans Tomcat par exemple, vous pouvez le configurer comme suit shared.loader propriété de Tomcat/conf/catalina.properties .

Si vous avez placé le foo.properties dans une structure de paquetage Java comme com.example alors vous devez le charger comme ci-dessous

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

Notez que le chemin d'accès d'un chargeur de classe contextuel ne doit pas commencer par un nom de domaine. / . Seulement lorsque vous utilisez un chargeur de classe "relatif" tel que SomeClass.class.getClassLoader() alors vous devez effectivement le faire démarrer avec un / .

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

Cependant, la visibilité du fichier de propriétés dépend alors du chargeur de classes en question. Il n'est visible que par le même class loader que celui qui a chargé la classe. Ainsi, si la classe est chargée par exemple par le server common classloader au lieu du webapp classloader, et que le fichier de propriétés se trouve dans la webapp elle-même, il est invisible. Le chargeur de classe contextuel est votre pari le plus sûr si vous pouvez placer le fichier de propriétés "partout" dans le classpath et/ou si vous avez l'intention de pouvoir remplacer un fichier fourni par le serveur à partir de la webapp.


2. Le mettre dans le contenu web

Pour que vous puissiez le charger en ServletContext#getResourceAsStream() avec un chemin relatif au webcontent :

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

Notez que j'ai démontré de placer le fichier dans /WEB-INF sinon il aurait été accessible au public par n'importe quel navigateur web. Notez également que le ServletContext est dans tout HttpServlet juste accessible par la classe héritée GenericServlet#getServletContext() et en Filter par FilterConfig#getServletContext() . Au cas où vous ne seriez pas dans une classe de servlet, elle est généralement injectable par l'intermédiaire de @Inject .


3. Le mettre dans le système de fichiers du disque local

Pour que vous puissiez le charger comme d'habitude java.io avec un chemin absolu du système de fichiers du disque local :

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

Notez l'importance d'utiliser un chemin absolu. Les chemins relatifs du système de fichiers du disque local sont absolument à proscrire dans une application Web Java EE. Voir aussi le premier lien "Voir aussi" ci-dessous.


Lequel choisir ?

Il suffit de peser les avantages/désavantages en votre sa propre opinion sur la maintenabilité.

Si les fichiers de propriétés sont "statiques" et ne doivent jamais être modifiés pendant l'exécution, vous pouvez les conserver dans le WAR.

Si vous préférez pouvoir modifier les fichiers de propriétés depuis l'extérieur de l'application web sans avoir à reconstruire et redéployer le WAR à chaque fois, mettez-le dans le classpath en dehors du projet (si nécessaire, ajoutez le répertoire au classpath).

Si vous préférez être en mesure de modifier les fichiers de propriétés de manière programmatique à partir de l'application web en utilisant Properties#store() en dehors de l'application web. Comme le Properties#store() nécessite un Writer il n'est pas possible d'utiliser un chemin d'accès au système de fichiers du disque. Ce chemin peut à son tour être transmis à l'application Web en tant qu'argument VM ou propriété système. Par précaution, jamais utiliser getRealPath() . Tous les changements dans le dossier de déploiement seront perdus lors d'un redéploiement pour la simple raison que les changements ne sont pas reflétés dans le fichier WAR original.

Voir aussi :

2 votes

"Je préfère personnellement le mettre dans le classpath en dehors du projet (ajouter un nouveau chemin au classpath)" confus, pouvez-vous donner un exemple ?

4 votes

@Blankman Il veut probablement dire créer un nouveau dossier, y placer tous vos fichiers de configuration personnalisés et ajouter ce dossier dans le classpath. Donc : 1) Créez un dossier appelé 'appconfs' quelque part (ce pourrait être même /etc/appconfs 2) Ajoutez ce dossier au classpath du serveur d'applications / domaine. La deuxième étape est spécifique au serveur d'applications, je ne pense pas qu'il y ait d'exemple générique pour cela.

0 votes

Re : 2 : Pourquoi les deux "WEB-INF/filename.properties" y "/WEB-INF/filename.properties" (remarquez le / au début) fonctionnent ? Y a-t-il une raison de préférer l'une plutôt que l'autre ?

10voto

user2822280 Points 21

Un avertissement : si vous placez des fichiers de configuration dans votre fichier WEB-INF/classes et que votre IDE, par exemple Eclipse, effectue un nettoyage/reconstruction, il détruira vos fichiers de configuration à moins qu'ils ne se trouvent dans le répertoire des sources Java. L'excellente réponse de BalusC fait allusion à cela dans l'option 1 mais je voulais insister.

J'ai appris à la dure que si vous "copiez" un projet web dans Eclipse, il effectue un nettoyage/reconstruction à partir de tous les dossiers sources. Dans mon cas, j'avais ajouté un "répertoire source lié" à partir de notre bibliothèque java POJO. WEB-INF/classes dossier. Faire un nettoyage/reconstruction dans ce projet (pas le projet de l'application web) a causé le même problème.

J'ai pensé à mettre mes confs dans le dossier POJO src, mais ces confs sont toutes pour des librairies tierces (comme Quartz ou URLRewrite) qui sont dans le dossier POJO. WEB-INF/lib dossier, donc ça n'avait pas de sens. J'ai l'intention d'essayer de le mettre dans le dossier "src" des projets web quand j'y arriverai, mais ce dossier est actuellement vide et avoir des fichiers de conf dans ce dossier semble inélégant.

Donc je vote pour mettre les fichiers de conf dans WEB-INF/commonConfFolder/filename.properties , suivant dans le dossier des classes, ce qui est l'option 2 de Balus.

1 votes

Si vous placez votre fichier de configuration dans un sous-dossier de WEB_INF, comment l'atteindre ? Je n'ai pas eu de chance avec 'configFiles/prop.properties' par exemple.

0 votes

Ok, cela fonctionne en plaçant le fichier de propriété sous 'Java Resources/src/', mais cela ne fonctionne pas à l'intérieur d'un de mes paquets et doit être à la racine de src. Votre avertissement sur le fait que le dossier des classes soit détruit est une préoccupation valide.

6voto

Ex : Dans le fichier web.xml la balise

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

Et chat.properties vous pouvez déclarer vos propriétés comme ceci

Pour Ex :

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.

5voto

Taylor Leese Points 18895

Il doit simplement être dans le classpath (c'est-à-dire s'assurer qu'il se trouve sous /WEB-INF/classes dans le fichier .war lors de la construction).

0 votes

Salut merci pour l'idée, mais il me dit que ne peut pas trouver le fichier spécifié, oui son problème de chemin comment donner le chemin

3voto

Kalpak Points 984

Vous pouvez vous avec votre dossier source de sorte que chaque fois que vous construisez, ces fichiers sont automatiquement copiés dans le répertoire des classes.

Au lieu d'utiliser un fichier de propriétés, utilisez un fichier XML.

Si les données sont trop petites, vous pouvez même utiliser web.xml pour accéder aux propriétés.

Veuillez noter que l'une de ces approches nécessitera le redémarrage du serveur d'applications pour que les changements soient pris en compte.

0 votes

J'ai placé dans le dossier webpages mais je n'arrive pas à y accéder l'erreur file not found arrive comment définir le chemin d'accès

1 votes

Si votre fichier se trouve dans le dossier WEB-INF/classes, il est automatiquement placé dans le classpath.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X