Où placer et comment lire les fichiers de ressources de configuration dans une application basée sur servlet?
dans mon application web , Je dois envoyer un e-mail à un ensemble d'utilisateurs prédéfinis comme finance@xyz.com
, donc je souhaite ajouter cela à un fichier .properties
et y accéder si nécessaire. Est-ce une procédure correcte, si oui, alors où dois-je placer ce fichier? J'utilise Netbeans IDE qui a deux dossiers séparés pour les fichiers source et JSP.
6 réponses
C'est votre choix. Il y a essentiellement trois façons dans une application Java Web archive (WAR):
1. Mettez-le dans classpath
pour que vous puissiez le charger par ClassLoader#getResourceAsStream()
avec un chemin relatif de classe:
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("foo.properties");
// ...
Properties properties = new Properties();
properties.load(input);
ici foo.properties
est supposé être placé dans l'une des racines qui sont couvertes par le chemin de classe par défaut d'une webapp, p.ex. webapp's /WEB-INF/lib
et /WEB-INF/classes
, du serveur /lib
, ou JDK/JRE /lib
. Si le fichier propertiesfile est spécifique à webapp, le mieux est de le placer dans /WEB-INF/classes
. Si vous développez un projet de guerre standard dans un IDE, déposez-le dans le dossier src
(le dossier source du projet). Si vous utilisez un projet Maven, déposez-le dans le dossier /main/resources
.
vous pouvez également le mettre quelque part en dehors de la classpath par défaut et ajouter son chemin à la classpath de la appserver. Dans Tomcat par exemple, vous pouvez le configurer comme shared.loader
propriété de Tomcat/conf/catalina.properties
.
si vous avez placé le foo.properties
it dans une structure de paquet 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 ce chemin d'un chargeur de classe de contexte ne doit pas commencer par un /
. Seulement lorsque vous utilisez un chargeur de classe " relative "tel que SomeClass.class.getClassLoader()
, alors vous devez en effet le 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 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 server common classloader au lieu de webapp classloader, et que le fichier de propriétés est à 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 de sorte que vous pouvez placer le fichier de propriétés "partout" dans le classpath et / ou vous avez l'intention de pouvoir remplacer un serveur fourni depuis le webapp on.
2. Mettez-le dans webcontent
pour que vous puissiez le charger par ServletContext#getResourceAsStream()
avec un contenu Web-chemin relatif:
InputStream input = getServletContext().getResourceAsStream("/WEB-INF/foo.properties");
// ...
notez que j'ai démontré avoir placé le fichier dans le dossier /WEB-INF
, sinon il aurait été accessible au public par n'importe quel internaute. Également notez que le ServletContext
est dans n'importe quelle classe HttpServlet
juste accessible par le GenericServlet#getServletContext()
et dans Filter
par FilterConfig#getServletContext()
. Dans le cas où vous n'êtes pas dans une classe de servlet, il est généralement juste injectable via @Inject
.
3. Mettez-le dans le système de fichiers Disque local
pour que vous puissiez le charger de la manière habituelle java.io
avec un disque local absolu chemin du système de fichiers:
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 Disque local sont un non-go absolu dans une application Web Java EE. Voir aussi le premier lien" Voir Aussi " ci-dessous.
que choisir?
il suffit de peser les avantages / désavantages dans votre propre opinion de la maintenabilité.
si la les fichiers de propriétés sont "statiques" et n'ont jamais besoin de changer pendant l'exécution, alors vous pouvez les garder dans la guerre.
si vous préférez pouvoir éditer des fichiers de propriétés à partir de l'extérieur de l'application web sans avoir à reconstruire et à redéployer la guerre à chaque fois, alors mettez-la dans classpath à l'extérieur du projet (si nécessaire, ajoutez le répertoire à classpath).
si vous préférez pouvoir modifier des fichiers de propriétés par programmation À partir de l'intérieur du web application utilisant la méthode Properties#store()
, mettez-la en dehors de l'application web. Comme le Properties#store()
nécessite un Writer
, vous ne pouvez pas vous déplacer en utilisant un chemin de système de fichiers disque. Ce chemin peut à son tour être passé à l'application web en tant qu'argument VM ou propriété du système. Par précaution, jamais utiliser getRealPath()
. Tous les changements dans le dossier deploy seront perdus sur un redéploiement pour la simple raison que les changements ne sont pas reflétés dans l'original La GUERRE de fichier.
voir aussi:
mot d'avertissement: si vous mettez des fichiers de config dans votre dossier WEB-INF/classes
, et votre IDE, disons Eclipse, fait un nettoyage/reconstruction, il nuke vos fichiers conf à moins qu'ils n'aient été dans le répertoire source Java. La grande réponse de BalusC fait allusion à cela dans l'option 1, mais j'ai voulu ajouter l'emphase.
j'ai appris de manière dure que si vous" copiez " un projet Web dans Eclipse, il fait un nettoyage/reconstruire à partir de n'importe quels dossiers source. Dans mon cas j'avais ajouté un "lien source dir" de notre POJO java bibliothèque, il compilerait dans le dossier WEB-INF/classes
. Faire un nettoyage / reconstruire 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 tous pour des libs tiers (comme Quartz ou URLRewrite) qui sont dans le dossier WEB-INF/lib
, donc ça n'avait pas de sens. J'ai l'intention de le mettre à l'essai dans le dossier "src" des projets web quand je m'en rendrai compte, mais ce dossier est actuellement vide et j'ai les fichiers conf semblent inélégants.
donc je vote pour mettre les fichiers conf dans WEB-INF/commonConfFolder/filename.properties
, suivant dans le dossier classes, qui est L'option Balus 2.
Ex: dans web.fichier 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.propriétés 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.
il suffit qu'il soit dans le chemin de la classe (alias assurez-vous qu'il se termine sous /WEB-INF/classes dans le .guerre dans le cadre de la construction).
vous pouvez vous servir de votre dossier source pour que chaque fois que vous construisez, ces fichiers soient automatiquement copiés dans le répertoire des classes.
au lieu d'utiliser le fichier de propriétés, utilisez le 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 n'importe laquelle de ces approches exigera le redémarrage du serveur app pour que les changements soient reflétés.
supposons que votre code est à la recherche du fichier say app.propriété. Copiez ce fichier à n'importe quel dir et ajoutez ce dir à classpath, en créant un setenv.sh dans la corbeille de tomcat.
dans votre setenv.sh de tomcat( si ce fichier n'existe pas, créez-en un , tomcat chargera ceci setenv.sh file.
#!/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.propriétés
Tomcat classe chargeur Outrepasser le avec celui de WEB-INF / classes /
une bonne lecture: https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html