Di mana menempatkan dan bagaimana membaca file sumber daya konfigurasi dalam aplikasi berbasis servlet?

222

Dalam aplikasi web saya, saya harus mengirim email ke set seperti yang [email protected]diinginkan pengguna , jadi saya ingin menambahkannya ke .propertiesfile dan mengaksesnya ketika diperlukan. Apakah ini prosedur yang benar, jika demikian maka di mana saya harus meletakkan file ini? Saya menggunakan Netbeans IDE yang memiliki dua folder terpisah untuk file sumber dan JSP.

sansknwoledge
sumber
JNDI mungkin bisa jadi solusi?
Basil Bourque

Jawaban:

464

Itu pilihanmu. Pada dasarnya ada tiga cara dalam arsip aplikasi web Java (PERANG):


1. Letakkan di classpath

Agar Anda dapat memuatnya ClassLoader#getResourceAsStream()dengan jalur relatif classpath:

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

Di sini foo.propertiesseharusnya ditempatkan di salah satu root yang dicakup oleh classpath default suatu webapp, misalnya webapp /WEB-INF/libdan /WEB-INF/classes, server /lib, atau JDK / JRE /lib. Jika propertiesfile khusus webapp, yang terbaik adalah menempatkannya di /WEB-INF/classes. Jika Anda mengembangkan proyek WAR standar dalam IDE, letakkan di srcfolder (folder sumber proyek). Jika Anda menggunakan proyek Maven, letakkan di /main/resourcesfolder.

Anda juga dapat meletakkannya di suatu tempat di luar classpath default dan menambahkan pathnya ke classpath appserver. Sebagai contoh, Tomcat Anda dapat mengkonfigurasinya sebagai shared.loaderproperti Tomcat/conf/catalina.properties.

Jika Anda telah menempatkannya foo.propertiesdalam struktur paket Java seperti com.example, maka Anda perlu memuatnya seperti di bawah ini

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

Perhatikan bahwa jalur pemuat kelas konteks ini tidak boleh dimulai dengan a /. Hanya ketika Anda menggunakan loader kelas "relatif" seperti SomeClass.class.getClassLoader(), maka Anda memang harus memulainya dengan a /.

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

Namun, visibilitas file properti tergantung pada pemuat kelas yang dimaksud. Ini hanya dapat dilihat oleh loader kelas yang sama dengan yang memuat kelas. Jadi, jika kelas dimuat oleh misalkan server common classloader alih-alih webapp classloader, dan file properti ada di dalam webapp itu sendiri, maka itu tidak terlihat. Pemuat kelas konteks adalah taruhan teraman Anda sehingga Anda dapat menempatkan file properti "di mana saja" di classpath dan / atau Anda bermaksud untuk dapat menimpa yang disediakan server dari webapp.


2. Masukkan ke dalam konten web

Agar Anda dapat memuatnya ServletContext#getResourceAsStream()dengan jalur relatif konten web:

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

Perhatikan bahwa saya telah menunjukkan untuk menempatkan file dalam /WEB-INFfolder, jika tidak maka file tersebut akan dapat diakses publik oleh browser web apa pun. Juga perhatikan bahwa ServletContextini ada di HttpServletkelas mana saja yang hanya dapat diakses oleh yang diwarisi GenericServlet#getServletContext()dan Filteroleh FilterConfig#getServletContext(). Jika Anda tidak berada dalam kelas servlet, biasanya hanya bisa diinjeksi melalui @Inject.


3. Masukkan ke dalam sistem file disk lokal

Sehingga Anda dapat memuatnya dengan java.iocara biasa dengan jalur sistem file disk lokal mutlak:

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

Perhatikan pentingnya menggunakan jalur absolut. Jalur sistem file disk lokal relatif adalah jalan keluar mutlak dalam aplikasi web Java EE. Lihat juga tautan "Lihat juga" pertama di bawah.


Yang mana yang harus dipilih?

Hanya menimbang keuntungan / kerugian menurut pendapat Anda sendiri tentang perawatan.

Jika file properti bersifat "statis" dan tidak perlu diubah selama runtime, maka Anda dapat menyimpannya dalam PERANG.

Jika Anda lebih suka dapat mengedit file properti dari luar aplikasi web tanpa perlu membangun kembali dan menggunakan kembali PERANG setiap kali, kemudian letakkan di classpath di luar proyek (jika perlu tambahkan direktori ke classpath).

Jika Anda lebih suka mengedit properti file secara terprogram dari dalam aplikasi web menggunakan Properties#store()metode, letakkan di luar aplikasi web. Karena Properties#store()memerlukan Writer, Anda tidak dapat berkeliling menggunakan jalur sistem file disk. Jalur itu pada gilirannya dapat diteruskan ke aplikasi web sebagai argumen VM atau properti sistem. Sebagai tindakan pencegahan, jangan pernah gunakangetRealPath() . Semua perubahan dalam folder deploy akan hilang pada penempatan ulang karena alasan sederhana bahwa perubahan tidak tercermin kembali dalam file WAR asli.

Lihat juga:

BalusC
sumber
2
"Saya pribadi lebih suka meletakkannya di classpath di luar proyek (tambahkan path baru ke classpath)" bingung, bisakah Anda memberi contoh?
Blankman
4
@ Blankman Dia mungkin berarti membuat folder baru, meletakkan semua file konfigurasi khusus Anda di sana, dan menambahkan folder itu ke classpath. Jadi: 1) Buat folder bernama 'appconfs' di suatu tempat (mungkin genap /etc/appconfs2) Tambahkan folder itu ke classpath server aplikasi / domain. Langkah kedua adalah server aplikasi khusus, saya tidak berpikir ada contoh umum untuk itu.
Tuukka Mustonen
Re: 2: Mengapa keduanya "WEB-INF/filename.properties"dan "/WEB-INF/filename.properties"(perhatikan /di awal) bekerja? Apakah ada alasan untuk lebih menyukai yang satu daripada yang lain?
Mr_and_Mrs_D
Saya telah memperbaiki masalah ini selama satu hari terakhir. Saya tidak dapat memuat file properti saya. Saya dapat memuatnya dari dua tempat. Salah satunya adalah direktori sistem dan satunya lagi adalah drive lokal. Ini bekerja dengan localhost. Tapi saya ingin menyebarkannya di amazon.
Arun Raja
Saya menggunakan netbeans IDE dan menyimpan file properti di Halaman Web / sumber daya. Saya mencoba mengaksesnya sebagai "./Web Pages / resources / config.properties". Saya tidak dapat mengaksesnya. Tolong bantu aku.
Arun Raja
9

Kata peringatan: jika Anda meletakkan file config di WEB-INF/classesfolder Anda , dan IDE Anda, katakanlah Eclipse, melakukan clean / rebuild, itu akan menghapus file conf Anda kecuali mereka berada di direktori source Java. Jawaban hebat BalusC menyinggung hal itu dalam opsi 1 tetapi saya ingin menambahkan penekanan.

Saya belajar dengan susah payah bahwa jika Anda "menyalin" proyek web di Eclipse, itu membersihkan / membangun kembali dari folder sumber apa pun. Dalam kasus saya, saya telah menambahkan "direktori sumber tertaut" dari perpustakaan java POJO kami, itu akan dikompilasi ke WEB-INF/classesfolder. Melakukan pembersihan / pembangunan kembali dalam proyek itu (bukan proyek aplikasi web) menyebabkan masalah yang sama.

Saya berpikir untuk meletakkan confs saya di folder POJO src, tetapi confs ini semua untuk lib pihak ke-3 (seperti Quartz atau URLRewrite) yang ada di WEB-INF/libfolder, jadi itu tidak masuk akal. Saya berencana untuk menguji meletakkannya di proyek web folder "src" ketika saya menyiasatinya, tetapi folder itu saat ini kosong dan memiliki file conf di dalamnya tampaknya tidak elegan.

Jadi saya memilih untuk meletakkan file conf WEB-INF/commonConfFolder/filename.properties, di sebelah folder kelas, yang merupakan opsi Balus 2.

Ed Pike
sumber
1
jika Anda meletakkan file config Anda di sub folder WEB_INF lalu bagaimana Anda mencapainya? Saya belum beruntung dengan mengatakan 'configFiles / prop.properties'
JesseBoyd
ok ini berfungsi meletakkan file properti di bawah 'Java Resources / src /' itu tidak bekerja dari dalam salah satu paket saya dan perlu di root src. peringatan Anda tentang folder kelas mendapatkan nuked adalah masalah yang valid.
JesseBoyd
6

Contoh: Dalam file web.xml tag

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

Dan chat.properties Anda dapat mendeklarasikan properti Anda seperti ini

Untuk 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
sumber
5

Itu hanya perlu berada di classpath (alias pastikan itu berakhir di bawah / WEB-INF / kelas di .war sebagai bagian dari build).

Taylor Leese
sumber
hai terima kasih atas idenya, tetapi ia memberi tahu saya bahwa tidak dapat menemukan file yang ditentukan, ya itu masalahnya jalan bagaimana memberikan jalan
sansknwoledge
3

Anda dapat dengan folder sumber Anda sehingga setiap kali Anda membangun, file-file itu secara otomatis disalin ke direktori kelas.

Alih-alih menggunakan file properti, gunakan file XML.

Jika datanya terlalu kecil, Anda bahkan dapat menggunakan web.xml untuk mengakses properti.

Harap perhatikan bahwa salah satu pendekatan ini akan meminta server aplikasi memulai ulang agar perubahan dapat tercermin.

Kalpak
sumber
saya ditempatkan di folder halaman web tetapi tidak dapat mengaksesnya file tidak ditemukan kesalahan datang bagaimana mengatur path
sansknwoledge
1
jika file Anda berakhir di folder WEB-INF / classes, file itu secara otomatis disetel ke classpath
Kalpak
2

Asumsikan kode Anda mencari file say app.properties. Salin file ini ke direktori apa saja dan tambahkan direktori ini ke classpath, dengan membuat setenv.sh di direktori bin dari kucing jantan.

Di setenv.sh dari tomcat Anda (jika file ini tidak ada, buat satu, tomcat akan memuat file setenv.sh ini. #!/bin/sh CLASSPATH="$CLASSPATH:/home/user/config_my_prod/"

Anda seharusnya tidak memiliki file properti Anda di ./webapps//WEB-INF/classes/app.properties

Pemuat kelas Tomcat akan menimpa dengan yang dari WEB-INF / classes /

Bacaan yang bagus: https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html

Thar
sumber