Mi piace .properties
files invece di
- JNDI - perché creare oggetti complessi durante la configurazione del programma invece del tempo di inizializzazione?
- proprietà di sistema:non è possibile configurare separatamente diverse istanze dello stesso WAR in un singolo Tomcat
- parametri di contesto - sono accessibili solo in
javax.servlet.Filter
,javax.servlet.ServletContextListener
che potrebbe essere scomodo
Tomcat 7 Context mantiene l'elemento Loader. Secondo il descrittore di deployment di docs (cosa in <Context>
tag) può essere inserito in:
$CATALINA_BASE/conf/server.xml
- cattivo - richiede il riavvio del server per rileggere la configurazione$CATALINA_BASE/conf/context.xml
- cattivo - condiviso tra tutte le applicazioni$CATALINA_BASE/work/$APP.war:/META-INF/context.xml
- cattivo - richiede il repackaging per cambiare la configurazione$CATALINA_BASE/work/[enginename]/[hostname]/$APP/META-INF/context.xml
- bello , ma vedi l'ultima opzione!!$CATALINA_BASE/webapps/$APP/META-INF/context.xml
- bello , ma vedi l'ultima opzione!!$CATALINA_BASE/conf/[enginename]/[hostname]/$APP.xml
- migliore - Completamente fuori dall'applicazione e scansionato automaticamente per le modifiche!!!
Context
può contenere Loader
personalizzato org.apache.catalina.loader.VirtualWebappLoader (disponibile nel moderno Tomcat 7, puoi aggiungere il tuo percorso di classe separato al tuo .properties
) e Parameter
(accessibile tramite FilterConfig.getServletContext().getInitParameter(name)
) e Environment
(accessibile tramite new InitialContext().lookup("java:comp/env").lookup("name")
):
<Context docBase="${basedir}/src/main/webapp"
reloadable="true">
<!-- http://tomcat.apache.org/tomcat-7.0-doc/config/context.html -->
<Resources className="org.apache.naming.resources.VirtualDirContext"
extraResourcePaths="/WEB-INF/classes=${basedir}/target/classes,/WEB-INF/lib=${basedir}/target/${project.build.finalName}/WEB-INF/lib"/>
<Loader className="org.apache.catalina.loader.VirtualWebappLoader"
virtualClasspath="${basedir}/target/classes;${basedir}/target/${project.build.finalName}/WEB-INF/lib"/>
<JarScanner scanAllDirectories="true"/>
<Parameter name="min" value="dev"/>
<Environment name="app.devel.ldap" value="USER" type="java.lang.String" override="true"/>
<Environment name="app.devel.permitAll" value="true" type="java.lang.String" override="true"/>
</Context>
Se usi Spring ed è XML config:
<context:property-placeholder location="classpath:app.properties"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@${db.host}:${db.port}:${db.user}"/>
<property name="username" value="${db.user}"/>
<property name="password" value="${db.pass}"/>
</bean>
Con Spring l'inserimento delle proprietà di cui sopra nei campi di fagioli è facile:
@Value("${db.user}") String defaultSchema;
invece di JNDI:
@Inject ApplicationContext context;
Enviroment env = context.getEnvironment();
String defaultSchema = env.getProperty("db.user");
Si noti inoltre che EL lo consente (valori predefiniti e sostituzione ricorsiva profonda):
@Value('${db.user:testdb}') private String dbUserName;
<property name='username' value='${db.user.${env}}'/>
Vedi anche:
- Aggiunta di una directory al percorso classe Tomcat
- Posso creare un percorso di classe personalizzato in base all'applicazione in Tomcat
- Come leggere un file delle proprietà al di fuori del mio contesto webapp in Tomcat
- Configura Tomcat per utilizzare il file delle proprietà per caricare le informazioni di connessione al DB
- Dovresti impostare le proprietà di connessione al database in server.xml o context.xml
- Esternalizza la configurazione di Tomcat
NOTA Con l'estensione del percorso di classe alla directory live hai anche consentito di esternalizzare qualsiasi altra configurazione , come logging, auth, ecc. Esternizzo logback.xml
in tal modo.
AGGIORNA Tomcat 8 modifica la sintassi per <Resources>
e <Loader>
elementi, la parte corrispondente ora ha il seguente aspetto:
<Resources>
<PostResources className="org.apache.catalina.webresources.DirResourceSet"
webAppMount="/WEB-INF/classes" base="${basedir}/target/classes" />
<PostResources className="org.apache.catalina.webresources.DirResourceSet"
webAppMount="/WEB-INF/lib" base="${basedir}/target/${project.build.finalName}/WEB-INF/lib" />
</Resources>
Il tuo tomcat/conf/Catalina/<host>
può contenere descrittori di contesto che consentono di configurare molte cose, inclusa la definizione di "voci di ambiente", accessibili da Java tramite JNDI. Ci sono molti modi per usarlo. Personalmente, ho impostato una voce di ambiente che è il percorso del file system al mio file delle proprietà. La mia app è creata per verificare questa voce e, se non esiste, cerca invece il file nel classpath. In questo modo, in dev, abbiamo le proprietà dev proprio lì sul classpath, ma quando compiliamo e distribuiamo, lo indirizziamo a un file esterno.
C'è una buona documentazione per la configurazione di un contesto sul sito web di Tomcat. Consulta la Definizione di un contesto sezione sui dettagli su come creare il file e dove metterlo.
Ad esempio, se il tuo host si chiama myHost
e la tua app è un file war chiamato myApp.war
nel webapps
directory, allora potresti creare tomcat/conf/Catalina/myHost/myApp.xml
con questo contenuto:
<Context>
<Environment name="configurationPath" value="/home/tomcat/myApp.properties" type="java.lang.String"/>
</Context>
Quindi, dal tuo codice, eseguirai una ricerca JNDI su java:comp/env/configurationPath
(certezza del 95% qui) per ottenere quel valore di stringa.
Puoi provare a inserire la tua configurazione (file delle proprietà) in Apache Tomcat\lib nel file JAR e rimuoverla dall'applicazione web. Quando il caricatore di classi di Tomcat non troverà la tua configurazione in webapp, proverà a trovarla nella directory "lib". Quindi puoi esternalizzare la tua configurazione semplicemente spostando la configurazione nella directory lib globale (è condivisa tra altre webapp).