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

222

Dans mon application Web, je dois envoyer un e-mail à un ensemble d'utilisateurs prédéfinis [email protected], je souhaite donc l'ajouter à un .propertiesfichier 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.

sansknwoledge
la source
JNDI pourrait peut-être être une solution?
Basil Bourque

Réponses:

464

C'est ton choix. Il existe essentiellement trois méthodes dans une archive d'application Web Java (WAR):


1. Mettez-le dans classpath

Pour que vous puissiez le charger ClassLoader#getResourceAsStream()avec un chemin relatif au chemin de classe:

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

Ici, foo.propertiesest censé être placé dans l'une des racines qui sont couvertes par le chemin de classe par défaut d'une webapp, par exemple les webapp /WEB-INF/libet les /WEB-INF/classesserveurs /libou les JDK / JRE /lib. Si le fichier de propriétés est spécifique à une application Web, le mieux est de le placer /WEB-INF/classes. Si vous développez un projet WAR standard dans un IDE, déposez-le dans le srcdossier (dossier source du projet). Si vous utilisez un projet Maven, déposez-le dans le /main/resourcesdossier.

Vous pouvez également le placer quelque part en dehors du chemin de classe par défaut et ajouter son chemin au chemin de classe du serveur d'applications. Dans Tomcat par exemple, vous pouvez le configurer comme shared.loaderpropriété de Tomcat/conf/catalina.properties.

Si vous l'avez placé foo.propertiesdans une structure de package Java comme com.example, vous devez le charger comme ci-dessous

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

Notez que ce chemin d'un chargeur de classe de contexte ne doit pas commencer par un /. Ce n'est que lorsque vous utilisez un chargeur de classe "relatif" tel que SomeClass.class.getClassLoader(), que vous devez en effet le démarrer avec a /.

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 classe en question. Il n'est visible que par le même chargeur de classe que celui qui a chargé la classe. Donc, si la classe est chargée par exemple par le chargeur de classe commun du serveur au lieu du chargeur de classe webapp, et que le fichier de propriétés se trouve à l'intérieur de webapp lui-même, alors il est invisible. Le chargeur de classe de contexte est votre pari le plus sûr, vous pouvez donc placer le fichier de propriétés "partout" dans le chemin de classe et / ou vous avez l'intention de remplacer un fichier fourni par le serveur à partir de la webapp.


2. Mettez-le dans le contenu Web

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

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

Notez que j'ai démontré de placer le fichier dans un /WEB-INFdossier, sinon il aurait été accessible au public par n'importe quel navigateur Web. Notez également que l' ServletContextest dans n'importe quelle HttpServletclasse juste accessible par l'héritage GenericServlet#getServletContext()et Filterpar FilterConfig#getServletContext(). Dans le cas où vous n'êtes pas dans une classe de servlet, il est généralement injectable via @Inject.


3. Mettez-le dans le système de fichiers du disque local

Pour que vous puissiez le charger de la java.iomanière habituelle avec un chemin d'accès absolu au 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 d'accès relatifs au système de fichiers du disque local sont une solution absolue dans une application Web Java EE. Voir aussi le premier lien "Voir aussi" ci-dessous.


Lequel choisir?

Il suffit de peser les avantages / inconvénients selon votre propre opinion de la maintenabilité.

Si les fichiers de propriétés sont "statiques" et n'ont jamais besoin d'ê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, alors placez-le dans le chemin de classe en dehors du projet (si nécessaire, ajoutez le répertoire au chemin de classe).

Si vous préférez pouvoir modifier les fichiers de propriétés par programme depuis l'intérieur de l'application Web à l'aide de la Properties#store()méthode, placez-le en dehors de l'application Web. Comme le Properties#store()requiert un Writer, vous ne pouvez pas vous déplacer en utilisant un chemin d'accès au système de fichiers disque. Ce chemin peut à son tour être transmis à l'application Web en tant qu'argument VM ou propriété système. Par précaution, ne jamais utilisergetRealPath() . Toutes les modifications dans le dossier de déploiement seront perdues lors d'un redéploiement pour la simple raison que les modifications ne sont pas reflétées dans le fichier WAR d'origine.

Voir également:

BalusC
la source
2
"Personnellement, je préfère le mettre dans le chemin de classe en dehors du projet (ajouter un nouveau chemin au chemin de classe)" confus, pouvez-vous donner un exemple?
Blankman
4
@Blankman Il signifie probablement créer un nouveau dossier, y placer tous vos fichiers de configuration personnalisés et ajouter ce dossier dans le chemin de classe. Donc: 1) Créez un dossier appelé 'appconfs' quelque part (peut-être même /etc/appconfs2) Ajoutez ce dossier au chemin de classe du serveur / domaine d'application. La deuxième étape est spécifique au serveur d'application, je ne pense pas qu'il y ait d'exemple générique pour cela.
Tuukka Mustonen du
Re: 2: Pourquoi les deux "WEB-INF/filename.properties"et "/WEB-INF/filename.properties"(remarquez /au début) fonctionneraient-ils? Y a-t-il une raison de préférer l'un à l'autre?
Mr_and_Mrs_D
J'ai été corrigé dans ce problème pour la dernière journée. Je ne parviens pas à charger mon fichier de propriétés. Je peux le charger depuis deux endroits. L'un est le répertoire système et l'autre le lecteur local. Cela fonctionne avec localhost. Mais je veux le déployer sur amazon.
Arun Raja
J'utilise l'EDI netbeans et conserve le fichier de propriétés dans les pages Web / ressources. J'essaie d'y accéder en tant que "./ Pages Web / ressources / config.properties". Je ne peux pas y accéder. Aidez-moi, s'il vous plaît.
Arun Raja
9

Mot d'avertissement: si vous placez des fichiers de configuration dans votre WEB-INF/classesdossier et que votre IDE, par exemple Eclipse, effectue un nettoyage / reconstruction, il nuke vos fichiers de conf à moins qu'ils ne se trouvent dans le répertoire source Java. La grande réponse de BalusC fait allusion à celle de l'option 1, mais je voulais ajouter de l'emphase.

J'ai appris à la dure que si vous "copiez" un projet Web dans Eclipse, il effectue un nettoyage / reconstruction à partir de n'importe quel dossier source. Dans mon cas, j'avais ajouté un " WEB-INF/classesrépertoire source lié" de notre bibliothèque java POJO, il se compilerait dans le dossier. Faire un nettoyage / reconstruction dans ce projet (pas le projet d'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 bibliothèques tierces (comme Quartz ou URLRewrite) qui sont dans le WEB-INF/libdossier, donc cela n'avait pas de sens. J'ai l'intention de le tester en le plaçant dans le dossier "src" des projets Web lorsque j'y arriverai, mais ce dossier est actuellement vide et avoir des fichiers conf semble inélégant.

Je vote donc pour la mise en place des fichiers conf WEB-INF/commonConfFolder/filename.properties, à côté du dossier classes, qui est l'option 2 de Balus.

Ed Pike
la source
1
si vous placez votre fichier de configuration dans un sous-dossier de WEB_INF, comment pouvez-vous y accéder? Je n'ai pas eu la chance de dire 'configFiles / prop.properties'
JesseBoyd
ok cela fonctionne en plaçant le fichier de propriétés sous 'Java Resources / src /' cela ne fonctionne pas depuis l'un de mes packages et doit être à la racine de src. votre avertissement au sujet du dossier de classes se nuked est une préoccupation valide.
JesseBoyd
6

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.
Subhash Pavuskar
la source
5

Il doit juste être dans le chemin de classe (aka assurez-vous qu'il se retrouve sous / WEB-INF / classes dans le .war dans le cadre de la construction).

Taylor Leese
la source
salut merci pour l'idée, mais il me dit que je ne trouve pas le fichier spécifié, oui c'est le problème de chemin comment donner le chemin
sansknwoledge
3

Vous pouvez vous avec votre dossier source afin 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 modifications soient prises en compte.

Kalpak
la source
i placé dans les pages Web dossier , mais incapable d' y accéder fichier non trouvé erreur vient comment chemin ensemble
sansknwoledge
1
si votre fichier se retrouve dans le dossier WEB-INF / classes, il est automatiquement placé dans le
chemin de classe
2

Supposons que votre code recherche le fichier, par exemple app.properties. Copiez ce fichier dans n'importe quel répertoire et ajoutez ce répertoire à classpath, en créant un setenv.sh dans le répertoire bin de tomcat.

Dans votre setenv.sh de tomcat (si ce fichier n'existe pas, créez-en un, tomcat chargera ce fichier setenv.sh. #!/bin/sh CLASSPATH="$CLASSPATH:/home/user/config_my_prod/"

Vous ne devriez pas avoir vos fichiers de propriétés dans ./webapps//WEB-INF/classes/app.properties

Le chargeur de classe Tomcat remplacera celui de WEB-INF / classes /

Une bonne lecture: https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html

Thar
la source