Gdzie umieścić i jak odczytać pliki zasobów konfiguracyjnych w aplikacji opartej na serwletach?

W mojej aplikacji internetowej muszę wysłać e-mail do zestawu predefiniowanych użytkowników, takich jak [email protected], więc chcę dodać to do pliku .properties i uzyskać do niego dostęp, gdy jest to wymagane. Czy jest to prawidłowa procedura, jeśli tak to gdzie mam umieścić ten plik? Używam NetBeans IDE, który ma dwa oddzielne foldery dla plików źródłowych i JSP.

Author: BalusC, 2010-01-29

6 answers

To twój wybór. Istnieją zasadniczo trzy sposoby w archiwum aplikacji internetowych Java (WAR):


1. Put it in classpath

Tak, że można go załadować przez ClassLoader#getResourceAsStream() ze ścieżką względną classpath:

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

Tutaj foo.properties powinien być umieszczony w jednym z korzeni, które są objęte domyślną ścieżką klas webapp, na przykład webapp /WEB-INF/lib i /WEB-INF/classes, Serwer /lib lub JDK / JRE /lib. Jeśli plik propertiesfile jest specyficzny dla webapp, najlepiej jest umieścić go w /WEB-INF/classes. Jeśli tworzysz standardowy projekt wojny w IDE, upuść go w folderze src (folder źródłowy projektu). Jeśli używasz projektu Maven, upuść go w folderze /main/resources.

Możesz też umieścić go gdzieś poza domyślną ścieżką classpath i dodać jego ścieżkę do ścieżki classpath serwera aplikacji. Na przykład w Tomcat można skonfigurować go jako shared.loader właściwość Tomcat/conf/catalina.properties.

Jeśli umieściłeś foo.properties w strukturze pakietu Java, takiej jak com.example, musisz załadować to jak poniżej

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

Zauważ, że ta ścieżka klasy kontekstowej loader nie powinna zaczynać się od /. Tylko wtedy, gdy używasz "względnego" loadera klas, takiego jak SomeClass.class.getClassLoader(), musisz zacząć go od /.

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

Widoczność pliku właściwości zależy wtedy od danej klasy loader. Jest widoczny tylko dla tej samej klasy co ta, która załadowała klasę. Tak więc, jeśli klasa jest ładowana przez np. Server common classloader zamiast webapp classloader, a Plik Właściwości znajduje się wewnątrz samej aplikacji webapp, a następnie jest niewidoczny. Context class loader jest najbezpieczniejszym zakładem, więc można umieścić plik właściwości "wszędzie" w classpath i / lub zamierzasz być w stanie zastąpić serwer pod warunkiem jeden z webapp na.


2. Put it in webcontent

Tak, że można go załadować przez ServletContext#getResourceAsStream() ze ścieżką webcontent-relative:

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

Zauważ, że zademonstrowałem umieszczenie pliku w /WEB-INF folderze, w przeciwnym razie byłby publicznie dostępny przez dowolny przeglądarkę internetową. Zauważ również, że {[23] } jest w dowolnej HttpServlet klasie dostępnej tylko przez odziedziczone GenericServlet#getServletContext() I in Filter by FilterConfig#getServletContext(). Jeśli nie należysz do klasy servletów, zwykle jest on wstrzykiwany przez @Inject.


3. Umieść go w lokalnym systemie plików dysku

Tak, że można go załadować w zwykły sposób java.io z absolutną ścieżką systemu plików na dysku lokalnym:

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

Zwróć uwagę na znaczenie używania absolutna ścieżka. Względne ścieżki systemu plików na dysku lokalnym są absolutnie nie do przejścia w aplikacji internetowej Java EE. Zobacz również pierwszy link "Zobacz także" poniżej.


Który wybrać?

Po prostu zważyć zalety / wady w swoją własną opinię o możliwości konserwacji.

Jeśli pliki właściwości są "statyczne" i nigdy nie muszą się zmieniać podczas wykonywania, możesz je zachować w stanie wojny.

Jeśli wolisz edytować pliki właściwości spoza aplikacja webowa bez konieczności każdorazowego przebudowywania i przeprogramowywania wojny, a następnie umieszczania jej w classpath poza projektem (w razie potrzeby dodaj katalog do classpath).

Jeśli wolisz edytować pliki właściwości programowo z poziomu aplikacji webowej przy użyciu metody Properties#store(), umieść je poza aplikacją webową. Ponieważ Properties#store() wymaga Writer, nie można używać ścieżki systemu plików na dysku. Ścieżka ta może z kolei zostać przekazana do aplikacji webowej jako maszyna wirtualna argument lub właściwość systemowa. Na wszelki wypadek, nigdy użyj getRealPath(). Wszystkie zmiany w folderze wdrożenia zostaną utracone po ponownym wdrożeniu z tego prostego powodu, że zmiany nie zostaną odzwierciedlone w oryginalnym pliku wojennym.

Zobacz też:

 427
Author: BalusC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:28

Słowo ostrzeżenia: jeśli umieścisz pliki konfiguracyjne w swoim folderze WEB-INF/classes, a twoje IDE, powiedzmy Eclipse, wykona czyszczenie/odbudowę, spowoduje to nuke plików conf, chyba że znajdują się one w katalogu źródłowym Javy. Świetna odpowiedź balusca nawiązuje do tego w opcji 1, ale chciałem dodać akcent.

Nauczyłem się na własnej skórze, że jeśli "skopiujesz" projekt WWW w Eclipse, robi on czyszczenie / przebudowę z dowolnego folderu źródłowego. W moim przypadku dodałem "linked source dir" z naszej biblioteki POJO java, skompilowałby się do folder WEB-INF/classes. Wykonanie czyszczenia/przebudowy w tym projekcie (nie w projekcie aplikacji internetowej) spowodowało ten sam problem.

Myślałem o umieszczeniu moich confów w folderze POJO src, ale te confy są dla bibliotek stron trzecich (takich jak Quartz lub URLRewrite), które są w folderze WEB-INF/lib, więc to nie miało sensu. Planuję przetestować umieszczenie go w folderze web projects "src", gdy się do niego przejdę, ale ten folder jest obecnie pusty i posiadanie w nim plików conf wydaje się nieeleganckie.

Więc głosuję za umieszczanie plików conf w WEB-INF/commonConfFolder/filename.properties, następnie do folderu classes, czyli opcji Balus 2.

 7
Author: Ed Pike,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-09 13:18:34

Ex: w sieci.plik xml znacznik

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

I czat.właściwości możesz zadeklarować swoje właściwości w następujący sposób

Dla 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.
 5
Author: Subhash Pavuskar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-27 03:03:42

Po prostu musi być w classpath (aka upewnij się, że kończy się pod /WEB-INF / classes w .wojny w ramach budowy).

 4
Author: Taylor Leese,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-29 09:47:43

Możesz użyć swojego folderu źródłowego, więc po zbudowaniu te pliki są automatycznie kopiowane do katalogu classes.

Zamiast używać pliku właściwości, użyj pliku XML.

Jeśli dane są zbyt małe, możesz nawet użyć web.xml do uzyskiwania dostępu do właściwości.

Należy pamiętać, że każda z tych metod wymaga ponownego uruchomienia serwera aplikacji, aby zmiany zostały odzwierciedlone.

 2
Author: Kalpak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-18 17:03:43

Załóżmy, że Twój kod szuka pliku say app.właściwości. Skopiuj ten plik do dowolnego katalogu i dodaj go do classpath, tworząc setenv.sh w bin dir tomcat.

W Twoim setenv.sh tomcat( jeśli ten plik nie istnieje, utwórz go, tomcat załaduje ten setenv.sh plik. #!/bin/sh CLASSPATH="$CLASSPATH:/home/user/config_my_prod/"

Nie powinieneś mieć plików właściwości w ./ webapps / / WEB-INF / classes / app.właściwości

Tomcat class loader nadpisze tą z WEB-INF / classes /

A dobra lektura: https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html

 0
Author: Thar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-04 19:36:52