أين يمكن وضعها وكيفية قراءة ملفات موارد التكوين في تطبيق Servlet؟

StackOverflow https://stackoverflow.com/questions/2161054

سؤال

في تطبيق الويب الخاص بي ، يجب أن أرسل بريدًا إلكترونيًا إلى مجموعة من المستخدمين المحددة مسبقًا مثل finance@xyz.com, ، لذلك أود أن أضيف ذلك إلى .properties الملف والوصول إليه عند الاقتضاء. هل هذا إجراء صحيح ، إذا كان الأمر كذلك ، فأين يجب أن أضع هذا الملف؟ أنا أستخدم NetBeans IDE التي تحتوي على مجلدين منفصلين لملفات Source و JSP.

هل كانت مفيدة؟

المحلول

إنه اختيارك. هناك أساسًا ثلاث طرق في أرشيف تطبيقات الويب Java (WAR):


1. ضعه في classpath

حتى تتمكن من تحميله بواسطة ClassLoader#getResourceAsStream() مع مسار العلاقة بين الفئة:

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

هنا foo.properties من المفترض أن يتم وضعها في أحد الجذور التي تغطيها classpath الافتراضي لـ webapp ، على سبيل المثال ويب. /WEB-INF/lib و /WEB-INF/classes, ، الخادم /lib, ، أو JDK/JRE'S /lib. إذا كانت PropertiesFile خاصة بـ WebApp ، فمن الأفضل وضعها في /WEB-INF/classes. إذا كنت تقوم بتطوير مشروع حرب قياسي في IDE ، فقم بإسقاطه في src المجلد (مجلد مصدر المشروع). إذا كنت تستخدم مشروع Maven ، فقم بإسقاطه في /main/resources مجلد.

يمكنك أيضًا وضعه في مكان ما خارج ClassPath الافتراضي وإضافة مساره إلى ClassPath من AppServer. على سبيل المثال ، يمكنك تكوينه على أنه shared.loader ممتلكات Tomcat/conf/catalina.properties.

إذا كنت قد وضعت foo.properties في بنية حزمة Java مثل com.example, ، ثم تحتاج إلى تحميله على النحو التالي

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

لاحظ أن هذا المسار من محمل فئة السياق يجب ألا يبدأ بـ /. فقط عندما تستخدم محمل فئة "نسبي" مثل SomeClass.class.getClassLoader(), ، ثم تحتاج بالفعل إلى البدء مع أ /.

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

ومع ذلك ، فإن رؤية ملف الخصائص تعتمد بعد ذلك على محمل الفصل المعني. إنه مرئي فقط لنفس تحميل الفئة مثل الذي قام بتحميل الفصل. لذلك ، إذا تم تحميل الفئة بواسطة EG Server CommonLoader بدلاً من WebApp ClassLoader ، وملف الخصائص داخل WebApp نفسه ، فهو غير مرئي. محمل فئة السياق هو رهانك الأكثر أمانًا حتى تتمكن من وضع ملف الخصائص "في كل مكان" في ClassPath و/أو تنوي أن تكون قادرًا على تجاوز واحد مقدم من الخادم من WebApp ON.


2. ضعها في موقع الويب

حتى تتمكن من تحميله بواسطة ServletContext#getResourceAsStream() مع مسار العلاقة بين الموقف الإلكتروني:

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

لاحظ أنني أثبتت وضع الملف فيه /WEB-INF المجلد ، وإلا كان يمكن الوصول إليه من قبل أي WebBrowser. لاحظ أيضًا أن ServletContext في أي HttpServlet الفصل يمكن الوصول إليه من قبل الموروثة GenericServlet#getServletContext() و في Filter بواسطة FilterConfig#getServletContext(). في حال لم تكن في فئة Servlet ، فعادة ما يكون ذلك مجرد حقن عبر @Inject.


3. ضعه في نظام ملفات القرص المحلي

حتى تتمكن من تحميله المعتاد java.io الطريق مع مسار نظام ملفات القرص المحلي المطلق:

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

لاحظ أهمية استخدام مسار مطلق. مسارات نظام ملفات القرص المحلية النسبية هي عبارة عن حدوث مطلقة في تطبيق الويب Java EE. انظر أيضًا الرابط "انظر أيضًا" أدناه.


التي تختار؟

فقط وزن المزايا/العيوب في لك رأي الخاص في الصيانة.

إذا كانت ملفات الخصائص "ثابتة" ولا تحتاج أبدًا إلى التغيير أثناء وقت التشغيل ، فيمكنك الاحتفاظ بها في الحرب.

إذا كنت تفضل أن تكون قادرًا على تحرير خصائص الملفات من خارج تطبيق الويب دون الحاجة إلى إعادة بناء الحرب وإعادة نشرها في كل مرة ، فضعها في ClassPath خارج المشروع (إذا لزم الأمر ، أضف الدليل إلى ClassPath).

إذا كنت تفضل أن تتمكن من تحرير خصائص الملفات بشكل برمجي من داخل تطبيق الويب باستخدام Properties#store() الطريقة ، ضعها خارج تطبيق الويب. كما Properties#store() الازعر Writer, ، لا يمكنك التجول باستخدام مسار نظام ملفات القرص. يمكن بدوره تمرير هذا المسار إلى تطبيق الويب كوسيطة VM أو خاصية النظام. كاحتياط، مطلقا استعمال getRealPath(). ستضيع جميع التغييرات في مجلد النشر على إعادة نشر لسبب بسيط هو أن التغييرات لا تنعكس مرة أخرى في ملف الحرب الأصلي.

أنظر أيضا:

نصائح أخرى

كلمة تحذير: إذا وضعت ملفات التكوين في WEB-INF/classes المجلد ، و IDE الخاص بك ، على سبيل المثال ، يقوم Eclipse ، بإعادة بناء نظيفة ، وسيؤدي ذلك إلى ملفات Conf الخاصة بك إلا إذا كانت في دليل مصدر Java. تشير إجابة Balusc الرائعة إلى ذلك في الخيار 1 ولكني أردت أن أضيف التركيز.

لقد تعلمت بالطريقة الصعبة أنه إذا قمت "بنسخ" مشروع ويب في Eclipse ، فإنه يقوم بعمل نظيف/إعادة بناء من أي مجلدات مصدر. في حالتي ، أضفت "مصدرًا مرتبطًا" من مكتبة Pojo Java الخاصة بنا ، وسوف يتم تجميعها إلى WEB-INF/classes مجلد. تسبب القيام بمشاركة نظيفة/إعادة بناء في هذا المشروع (وليس مشروع تطبيق الويب) في نفس المشكلة.

فكرت في وضع confs الخاص بي في مجلد Pojo SRC ، ولكن هذه كلها هي من أجل libs الطرف الثالث (مثل الكوارتز أو urlrewrite) الموجودة في WEB-INF/lib المجلد ، بحيث لم يكن منطقيا. أخطط لاختبار وضعه في مجلد مشاريع الويب "SRC" عندما أتجول إليه ، لكن هذا المجلد فارغ حاليًا ويحتوي على ملفات conf في الأمر.

لذلك أصوت لوضع ملفات conf في WEB-INF/commonConfFolder/filename.properties, التالي إلى مجلد الفصول ، وهو خيار بالوس 2.

على سبيل المثال: في ملف web.xml العلامة

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

و chat.properties يمكنك إعلان خصائصك مثل هذا

لـ 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.

يجب أن يكون فقط في ClassPath (ويعرف أيضًا باسم فئات /فئات الويب /Web-INF في .WAR كجزء من البناء).

يمكنك مع مجلد المصدر الخاص بك ، لذلك كلما قمت بإنشاء ، يتم نسخ هذه الملفات تلقائيًا إلى دليل الفئات.

بدلاً من استخدام ملف الخصائص ، استخدم ملف XML.

إذا كانت البيانات صغيرة جدًا ، فيمكنك حتى استخدام web.xml للوصول إلى الخصائص.

يرجى ملاحظة أن أيًا من هذه النهج سيتطلب إعادة تشغيل خادم التطبيق للتغييرات التي يجب أن تنعكس.

افترض أن الكود الخاص بك يبحث عن الملف say App.properties. انسخ هذا الملف إلى أي dir وأضف هذا dir to classpath ، عن طريق إنشاء setenv.sh في bin dir of tomcat.

في setenv.sh من Tomcat (إذا لم يكن هذا الملف موجودًا ، فإن إنشاء واحد ، سيقوم Tomcat بتحميل ملف Setenv.sh هذا. #!/bin/sh CLASSPATH="$CLASSPATH:/home/user/config_my_prod/"

يجب ألا يكون لديك ملفات الخصائص الخاصة بك في ./webapps//web-inf/classes/app.properties

سوف يقوم Tomcat Class Loader بتجاوز واحد من Web-Inf/Classes/

قراءة جيدة:https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top