Servlet tabanlı uygulamada yapılandırma kaynak dosyalarını nereye yerleştirmeli ve nasıl okumalıyım?


222

Web uygulamamda önceden tanımlanmış kullanıcılara e-posta göndermem gerekiyor finance@xyz.com, bu yüzden bunu bir .propertiesdosyaya eklemek ve gerektiğinde erişmek istiyorum. Bu doğru bir yordam mı, öyleyse bu dosyayı nereye yerleştirmeliyim? Kaynak ve JSP dosyaları için iki ayrı klasör olan Netbeans IDE kullanıyorum.


JNDI belki bir çözüm olabilir?
Basil Bourque

Yanıtlar:


464

Seçim senin. Bir Java web uygulaması arşivinde (WAR) temel olarak üç yol vardır:


1. Sınıf yoluna koy

Böylece ClassLoader#getResourceAsStream()sınıf yoluna bağlı bir yolla yükleyebilirsiniz :

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

Burada foo.properties, bir web uygulamasının varsayılan sınıfyolunun (ör. Webapp /WEB-INF/libve /WEB-INF/classessunucu /lib, JDK / JRE) kapsanan köklerden birine yerleştirilmesi gerekir /lib. Propertiesfile webapp-özgü ise, en iyisi onu yerleştirmektir /WEB-INF/classes. IDE'de standart bir WAR projesi geliştiriyorsanız src, projeye (projenin kaynak klasörü) bırakın . Bir Maven projesi kullanıyorsanız projeye bırakın/main/resources klasöre .

Alternatif olarak, varsayılan sınıfyolunun dışında bir yere koyabilir ve yolunu uygulama sunucusunun sınıfyoluna ekleyebilirsiniz. Örneğin Tomcat'i shared.loaderözelliği olarak yapılandırabilirsiniz Tomcat/conf/catalina.properties.

foo.propertiesBir Java paket yapısına yerleştirdiyseniz,com.example aşağıdaki gibi yüklemeniz gerekir

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

Bağlam sınıfı yükleyicinin bu yolunun a ile başlamaması gerektiğini unutmayın /. Yalnızca "göreceli" sınıf yükleyiciyi kullandığınızda SomeClass.class.getClassLoader(), gerçekten bir/ .

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

Ancak, özellikler dosyasının görünürlüğü söz konusu sınıf yükleyiciye bağlıdır. Yalnızca sınıfı yükleyenle aynı sınıf yükleyicisi tarafından görülebilir. Bu nedenle, sınıf webapp sınıf yükleyicisi yerine sunucu ortak sınıf yükleyicisi tarafından yüklenirse ve özellikler dosyası web uygulamasının kendisindeyse, görünmez olur. Bağlam sınıfı yükleyicisi en güvenli bahistir, bu nedenle sınıf dosyasına "her yerde" özellikler dosyasını yerleştirebilir ve / veya sunucu tarafından sağlanan bir web uygulamasından geçersiz kılmayı düşünebilirsiniz.


2. Web içeriğine koyun

Böylece, web ServletContext#getResourceAsStream()içerik göreli bir yolla yükleyebilirsiniz :

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

Dosyayı /WEB-INFklasöre yerleştirdiğimi gösterdim , aksi takdirde herhangi bir webbrowser tarafından halka açık olurdu. Ayrıca unutmayın ServletContextherhangi bir HttpServletmiras ile sadece erişilebilir sınıfta GenericServlet#getServletContext()ve Filtertarafından FilterConfig#getServletContext(). Bir sunucu uygulaması sınıfında değilseniz, genellikle sadece enjekte edilebilir @Inject.


3. Yerel disk dosya sistemine yerleştirin

Böylece, java.iomutlak bir yerel disk dosya sistemi yolu ile her zamanki gibi yükleyebilirsiniz :

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

Mutlak yol kullanmanın önemine dikkat edin. Göreli yerel disk dosya sistemi yolları, bir Java EE web uygulamasında mutlak hareketsizdir. Ayrıca aşağıdaki ilk "Ayrıca bkz." Bağlantısına bakın.


Hangisini seçmeli?

Sadece içeri avantajları / dezavantajları tartmak senin yönetilebilirliğinin kendi görüşünü.

Özellikler dosyaları "statik" ise ve çalışma zamanı sırasında hiçbir zaman değişmeleri gerekmiyorsa, bunları SAVAT'ta tutabilirsiniz.

Her seferinde WAR'ı yeniden oluşturmaya ve yeniden konuşlandırmaya gerek kalmadan özellik dosyalarını web uygulamasının dışından düzenlemeyi tercih ediyorsanız, projenin dışındaki sınıf yoluna yerleştirin (gerekirse dizini sınıf yoluna ekleyin).

Özellik dosyalarını Properties#store()yöntem kullanarak web uygulamasının içinden programlı olarak düzenleyebilmeyi tercih ediyorsanız, dosyayı web uygulamasının dışına yerleştirin. A'nın Properties#store()gerektirdiği gibi, Writerbir disk dosya sistemi yolu kullanarak dolaşamazsınız. Bu yol da bir VM argümanı veya sistem özelliği olarak web uygulamasına aktarılabilir. Önlem olarak, asla kullanmayıngetRealPath() . Konuşlandırma klasöründeki tüm değişiklikler, değişikliklerin orijinal WAR dosyasına geri yansıtılmaması nedeniyle yeniden dağıtımda kaybolur.

Ayrıca bakınız:


2
"Şahsen projenin dışında sınıf yoluna koymayı tercih ediyorum (sınıf yoluna yeni bir yol ekleyin)" karıştı, bir örnek verebilir misiniz?
Blankman

4
@Blankman Muhtemelen yeni bir klasör oluşturmak, tüm özel yapılandırma dosyalarınızı buraya koymak ve bu klasörü sınıfyoluna eklemek anlamına gelir. Yani: 1) Bir yerde 'appconfs' adlı bir klasör oluşturun (hatta /etc/appconfs2 olabilir ) Bu klasörü uygulama sunucusu / alan sınıfına ekleyin. İkinci adım uygulama sunucusuna özel, bunun için genel bir örnek olduğunu sanmıyorum.
Tuukka Mustonen

Re: 2: Neden hem "WEB-INF/filename.properties"ve "/WEB-INF/filename.properties"( /başlangıçta fark ) işe yarayacak? Birini diğerine tercih etmek için herhangi bir sebep var mı?
Mr_and_Mrs_D

Bu konuda son bir gündür giderildim. Özellikler dosyamı yükleyemiyorum. İki yerden yükleyebiliyorum. Biri sistem dizini, diğeri ise yerel sürücü. Localhost ile çalışır. Ama onu Amazon'a yerleştirmek istiyorum.
Arun Raja

Netbeans IDE kullanıyorum ve özellikler dosyasını Web Sayfalarında / kaynaklarında tutuyorum. "./Web Pages / resources / config.properties" olarak erişmeye çalışıyorum. Erişemiyorum. Lütfen bana yardım et.
Arun Raja

9

Uyarı kelimesi: Yapılandırma dosyalarını WEB-INF/classesklasörünüze koyarsanız ve Eclipse gibi IDE'niz temiz / yeniden oluştur yaparsa, Java kaynak dizininde olmadıkları sürece conf dosyalarınızı çağıracaktır. BalusC'in büyük cevabı 1. seçenekte bununla ilgili ama vurgulamak istedim.

Eclipse'de bir web projesini "kopyalarsanız", herhangi bir kaynak klasöründen bir temiz / yeniden oluşturması zor yoldan öğrendim. Benim durumumda POJO java kütüphanemizden bir "bağlantılı kaynak dizin" ekledim,WEB-INF/classes klasöre derlenir. Bu projede bir temizleme / yeniden oluşturma (web uygulaması projesi değil) aynı soruna neden oldu.

Benim confs POJO src klasörüne koymayı düşündüm, ama bu confs hepsi klasörde olan 3. parti libs (Quartz veya URLRewrite gibi) içindir WEB-INF/lib, bu yüzden mantıklı değildi. Ben bunu almak zaman web projeleri "src" klasörüne koyarak test etmeyi planlıyorum, ama bu klasör şu anda boş ve içinde conf dosyaları olması yetersiz görünüyor.

İçinde conf dosyalarını koymak için ben oylama Yani WEB-INF/commonConfFolder/filename.properties, bir sonraki Balus seçenek 2'dir sınıflar klasörüne.


1
config dosyanızı WEB_INF alt klasörüne koyarsanız, dosyaya nasıl ulaşırsınız? 'ConfigFiles / prop.properties' demekle şansım olmadı
JesseBoyd

Tamam, bu özellik dosyasını 'Java Resources / src /' altına koyarak çalışır, paketlerimden birinde çalışmaz ve src'nin kökünde olması gerekir. nuked almak klasörler hakkında uyarı geçerli bir endişe.
JesseBoyd

6

Örn: web.xml dosyasında etiketi

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

Ve chat.properties gibi mülklerinizi ilan edebilirsiniz

Örn:

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.

5

Sadece sınıf yolunda olması gerekir (aka, yapının bir parçası olarak .war içinde / WEB-INF / sınıfları altında kaldığından emin olun).


merhaba fikir için teşekkürler, ama bana belirtilen dosyayı bulamadığını söyler, evet bu yol sorunu nasıl yol vermek
sansknwoledge

3

Kaynak klasörünüzle yapabilirsiniz, böylece her oluşturduğunuzda, bu dosyalar otomatik olarak sınıflar dizinine kopyalanır.

Özellikler dosyasını kullanmak yerine XML dosyası kullanın.

Veriler çok küçükse, özelliklere erişmek için web.xml dosyasını da kullanabilirsiniz.

Bu yaklaşımlardan herhangi birinin değişikliklerin yansıtılması için uygulama sunucusunun yeniden başlatılmasını gerektireceğini lütfen unutmayın.


i webpages klasörüne yerleştirilir ama dosyaya erişemiyorum hata bulunamadı yolu ayarlamak için geliyor
sansknwoledge

1
dosyanız WEB-INF / classes klasöründe sona ererse, otomatik olarak sınıf yoluna ayarlanır
Kalpak

2

Kodunuzun app.properties adlı dosyayı aradığını varsayalım. Bu dosyayı herhangi bir dizine kopyalayın ve tomcat'in bin dizininde bir setenv.sh oluşturarak bu dizini classpath öğesine ekleyin.

Tomcat'in setenv.sh dosyasında (bu dosya yoksa, bir tane oluşturun, tomcat bu setenv.sh dosyasını yükler. #!/bin/sh CLASSPATH="$CLASSPATH:/home/user/config_my_prod/"

./Webapps//WEB-INF/classes/app.properties dosyasında mülk dosyalarınız olmamalıdır.

Tomcat sınıfı yükleyici, WEB-INF / classes /

İyi bir okuma: https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.