Dove posizionare e come leggere i file delle risorse di configurazione nell'applicazione basata su servlet?


222

Nella mia applicazione web devo inviare e-mail a gruppi di utenti predefiniti come finance@xyz.com, quindi desidero aggiungerlo a un .propertiesfile e accedervi quando richiesto. È una procedura corretta, in tal caso, dove devo posizionare questo file? Sto usando Netbeans IDE che ha due cartelle separate per i file sorgente e JSP.


JNDI forse potrebbe essere una soluzione?
Basil Bourque,

Risposte:


464

È la vostra scelta. Esistono sostanzialmente tre modi in un archivio di applicazioni Web (WAR) Java:


1. Mettilo nel percorso di classe

In modo che tu possa caricarlo ClassLoader#getResourceAsStream()con un percorso relativo al classpath:

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

Qui foo.propertiesdovrebbe essere collocato in una delle radici che sono coperte dal percorso di classe predefinito di una webapp, ad esempio webapp /WEB-INF/libe /WEB-INF/classes, server /libo JDK / JRE /lib. Se il file delle proprietà è specifico di webapp, è consigliabile inserirlo /WEB-INF/classes. Se stai sviluppando un progetto WAR standard in un IDE, rilascialo nella srccartella (la cartella di origine del progetto). Se stai usando un progetto Maven, lascialo nella /main/resourcescartella.

In alternativa puoi anche metterlo da qualche parte fuori dal percorso di classe predefinito e aggiungere il suo percorso al percorso di classe del server applicazioni. Ad esempio, Tomcat è possibile configurarlo come shared.loaderproprietà di Tomcat/conf/catalina.properties.

Se lo hai inserito foo.propertiesin una struttura di pacchetto Java come com.example, allora devi caricarlo come di seguito

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

Si noti che questo percorso di un caricatore di classi di contesto non deve iniziare con a /. Solo quando stai usando un caricatore di classe "relativo" come SomeClass.class.getClassLoader(), allora devi davvero avviarlo con a /.

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

Tuttavia, la visibilità del file delle proprietà dipende quindi dal caricatore di classi in questione. È visibile solo allo stesso caricatore di classi di quello che ha caricato la classe. Quindi, se la classe viene caricata ad es. Da un comune caricatore di classi del server anziché dal caricatore di classi webapp e il file delle proprietà si trova all'interno di webapp stesso, allora è invisibile. Il caricatore di classi di contesto è la scommessa più sicura in modo da poter posizionare il file delle proprietà "ovunque" nel percorso di classe e / o si intende essere in grado di sovrascrivere uno fornito dal server dalla webapp su.


2. Inseriscilo in un contenuto web

In modo che tu possa caricarlo ServletContext#getResourceAsStream()con un percorso relativo al webcontent:

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

Si noti che ho dimostrato di posizionare il file nella /WEB-INFcartella, altrimenti sarebbe stato accessibile al pubblico da qualsiasi browser web. Si noti inoltre che ServletContextè in qualsiasi HttpServletclasse appena accessibile dall'ereditato GenericServlet#getServletContext()e in Filterda FilterConfig#getServletContext(). Nel caso in cui non sei in una classe servlet, di solito è solo iniettabile tramite @Inject.


3. Inserirlo nel file system del disco locale

In modo da poterlo caricare nel solito java.iomodo con un percorso di file system del disco locale assoluto:

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

Nota l'importanza di utilizzare un percorso assoluto. I percorsi relativi del file system del disco locale sono assolutamente inutili in un'applicazione Web Java EE. Vedi anche il primo link "Vedi anche" di seguito.


Quale scegliere?

Basta valutare i vantaggi / gli svantaggi secondo la propria opinione sulla manutenibilità.

Se i file delle proprietà sono "statici" e non devono mai essere modificati durante il runtime, è possibile conservarli in WAR.

Se si preferisce poter modificare i file delle proprietà dall'esterno dell'applicazione Web senza la necessità di ricostruire e ridistribuire il WAR ogni volta, inserirlo nel percorso di classe all'esterno del progetto (se necessario aggiungere la directory al percorso di classe).

Se si preferisce essere in grado di modificare i file delle proprietà a livello di codice dall'interno dell'applicazione Web utilizzando il Properties#store()metodo, inserirlo all'esterno dell'applicazione Web. Come Properties#store()richiesto a Writer, non è possibile andare in giro utilizzando un percorso del file system del disco. Tale percorso può a sua volta essere passato all'applicazione Web come argomento VM o proprietà di sistema. Per precauzione, non usare maigetRealPath() . Tutte le modifiche nella cartella di distribuzione andranno perse durante una ridistribuzione per il semplice motivo che le modifiche non vengono riportate nel file WAR originale.

Guarda anche:


2
"Personalmente preferisco metterlo nel percorso di classe al di fuori del progetto (aggiungi un nuovo percorso al percorso di classe)" confuso, puoi fare un esempio?
Blankman,

4
@Blankman Probabilmente intende creare una nuova cartella, mettere lì tutti i tuoi file di configurazione personalizzati e aggiungere quella cartella nel percorso di classe. Quindi: 1) Crea una cartella chiamata 'appconfs' da qualche parte (potrebbe anche essere /etc/appconfs2) Aggiungi quella cartella al percorso di classe del server / dominio dell'app. Il secondo passo è specifico del server delle app, non credo che ci sia un esempio generico per quello.
Tuukka Mustonen,

Ri: 2: Perché entrambi "WEB-INF/filename.properties"e "/WEB-INF/filename.properties"(si noti /all'inizio) funzionano? C'è qualche motivo per preferire l'uno rispetto all'altro?
Mr_and_Mrs_D

Sono stato risolto in questo problema un giorno fa. Non riesco a caricare il mio file delle proprietà. Sono in grado di caricarlo da due punti. Uno è la directory di sistema e uno è l'unità locale. Funziona con localhost. Ma voglio distribuirlo su Amazon.
Arun Raja,

Sto usando netbeans IDE e mantengo il file delle proprietà in pagine Web / risorse. Provo ad accedervi come "./Web Pagine / risorse / config.properties". Non riesco ad accedervi. Mi aiuti per favore.
Arun Raja,

9

Avvertenza: se metti i file di configurazione nella tua WEB-INF/classescartella e il tuo IDE, ad esempio Eclipse, esegue una pulizia / ricostruzione, rovinerà i file di configurazione a meno che non si trovassero nella directory di origine Java. La grande risposta di BalusC allude a quella nell'opzione 1 ma volevo aggiungere enfasi.

Ho imparato a fondo che se "copi" un progetto Web in Eclipse, esegue una pulizia / ricostruzione da qualsiasi cartella di origine. Nel mio caso avevo aggiunto una " WEB-INF/classesdirectory sorgente collegata" dalla nostra libreria java POJO, che sarebbe stata compilata nella cartella. Fare una pulizia / ricostruzione in quel progetto (non nel progetto dell'app Web) ha causato lo stesso problema.

Ho pensato di mettere i miei conf nella cartella POJO src, ma questi conf sono tutti per librerie di terze parti (come Quartz o URLRewrite) che si trovano nella WEB-INF/libcartella, quindi non ha senso. Ho intenzione di provare a metterlo nella cartella "src" dei progetti Web quando ci arrivo, ma quella cartella è attualmente vuota e con i file conf in essa sembra non elegante.

Quindi voto per aver inserito i file conf WEB-INF/commonConfFolder/filename.properties, accanto alla cartella delle classi, che è l'opzione 2 di Balus.


1
se metti il ​​tuo file di configurazione in una sottocartella di WEB_INF, come lo raggiungi? Non ho avuto fortuna con dire 'configFiles / prop.properties'
JesseBoyd

ok questo funziona mettendo il file delle proprietà in 'Risorse Java / src /' non funziona all'interno di uno dei miei pacchetti e deve essere alla radice di src. il tuo avvertimento sulla cartella delle classi che viene rovinata è una preoccupazione valida.
JesseBoyd,

6

Esempio: nel file web.xml il 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>

E chat.properties puoi dichiarare le tue proprietà in questo modo

Per esempio:

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

Deve solo essere nel classpath (ovvero assicurarsi che finisca in / WEB-INF / classes in .war come parte della build).


ciao grazie per l'idea, ma mi dice che non riesco a trovare il file specificato, sì, è il problema del percorso come dare il percorso
sansknwoledge

3

Puoi farlo con la tua cartella di origine, quindi ogni volta che compili, quei file vengono automaticamente copiati nella directory delle classi.

Invece di utilizzare il file delle proprietà, utilizzare il file XML.

Se i dati sono troppo piccoli, puoi persino usare web.xml per accedere alle proprietà.

Si noti che uno di questi approcci richiederà il riavvio del server app per riflettere le modifiche.


ho inserito nella cartella delle pagine Web ma non riesco ad accedervi il file non trovato errore sta arrivando come impostare il percorso
sansknwoledge

1
se il tuo file finisce nella cartella WEB-INF / classes, viene automaticamente impostato nel percorso di classe
Kalpak

2

Supponiamo che il tuo codice stia cercando il file, ad esempio app.properties. Copia questo file in qualsiasi directory e aggiungi questa directory al classpath, creando un setenv.sh nella directory bin di tomcat.

Nel tuo setenv.sh di tomcat (se questo file non esiste, creane uno, tomcat caricherà questo file setenv.sh. #!/bin/sh CLASSPATH="$CLASSPATH:/home/user/config_my_prod/"

Non dovresti avere i tuoi file delle proprietà in ./webapps//WEB-INF/classes/app.properties

Il caricatore di classi Tomcat sovrascriverà quello con WEB-INF / classes /

Una buona lettura: https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.