Внешняя конфигурация Tomcat
У меня есть конфигурация DataSource в context.xml. Можно ли не жестко кодировать параметры базы данных в этом файле? Например, используйте внешний файл свойств и загрузите из него параметры?
Что-то вроде:
context.xml:
<Resource
name="jdbc/myDS" auth="Container"
type="javax.sql.DataSource"
driverClassName="oracle.jdbc.OracleDriver"
url="${db.url}"
username="${db.user}"
password="${db.pwd}"
maxActive="2"
maxIdle="2"
maxWait="-1"/>
db.properties:
db.url=jdbc:oracle:thin:@server:1521:sid
db.user=test
db.pwd=test
Ответы
Ответ 1
Как указано здесь, вы можете сделать это следующим образом.
1. Загрузите библиотеку tomcat, чтобы получить определение интерфейса, например, определяя зависимость от maven:
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-coyote</artifactId>
<version>7.0.47</version>
</dependency>
2. Следующим шагом является создание com.mycompany.MyPropertyDecoder следующим образом:
import org.apache.tomcat.util.IntrospectionUtils;
public class MyPropertyDecoder implements IntrospectionUtils.PropertySource {
@Override
public String getProperty(String arg0) {
//TODO read properties here
return null;
}
}
3.Put MyPropertyDecoder.class в папку tomcat7/lib
4.Define org.apache.tomcat.util.digester. Свойство PROPERTY_SOURCE: tomcat7/conf/catalina.properties:
org.apache.tomcat.util.digester.PROPERTY_SOURCE=com.mycompany.MyPropertyDecoder
5.Update your context.xml со свойствами vars
<Resource name="jdbc/TestDB"
auth="Container"
type="javax.sql.DataSource"
username="root"
password="${db.password}"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/mysql?autoReconnect=true"
...
6.Put application.properties файл где-нибудь в вашем проекте/контейнере
7. Убедитесь, что MyPropertyDecoder правильно читает application.properties
8.Enjoy!
PS Также существует аналогичный подход, описанный для tc Server.
Ответ 2
Легко с контекстные дескрипторы развертывания, которые выглядят так:
<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>
Есть несколько мест, где вы можете поместить эту конфигурацию, так как мой лучший вариант $CATALINA_BASE/conf/[enginename]/[hostname]/$APP.xml
В приведенном выше XML Context
может храниться пользовательский Loader
org.apache.catalina.loader.VirtualWebappLoader (доступен в современном Tomcat 7, вы можете добавить собственный отдельный путь к каждому приложению к вашим файлам .properties
), Parameter
(доступ через FilterConfig.getServletContext().getInitParameter(name)
) и Environment
(доступ через new InitialContext().lookup("java:comp/env").lookup("name")
)
См. обсуждение по адресу:
ОБНОВЛЕНИЕ Синтаксис изменения Tomcat 8 для элементов <Resources>
и <Loader>
, теперь соответствующая часть выглядит
<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>
Ответ 3
Конечно, это возможно. Вы должны зарегистрировать ServletContextListener в своем web.xml
следующим образом:
<!-- at the beginning of web.xml -->
<listener>
<listener-class>com.mycompany.servlets.ApplicationListener</listener-class>
</listener>
Источник com.mycompany.servlets.ApplicationListener
:
package com.mycompany.servlets;
public class ApplicationListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
// this method is invoked once when web-application is deployed (started)
// reading properties file
FileInputStream fis = null;
Properties properties = new Properties();
try {
fis = new FileInputStream("path/to/db.properties")
properties.load(fis);
} catch(IOException ex) {
throw new RuntimeException(ex);
} finally {
try {
if(fis != null) {
fis.close();
}
} catch(IOException e) {
throw new RuntimeException(e);
}
}
// creating data source instance
SomeDataSourceImpl dataSource = new SomeDataSourceImpl();
dataSource.setJdbcUrl(properties.getProperty("db.url"));
dataSource.setUser(properties.getProperty("db.user"));
dataSource.setPassword(properties.getProperty("db.pwd"));
// storing reference to dataSource in ServletContext attributes map
// there is only one instance of ServletContext per web-application, which can be accessed from almost anywhere in web application(servlets, filters, listeners etc)
final ServletContext servletContext = servletContextEvent.getServletContext();
servletContext.setAttribute("some-data-source-alias", dataSource);
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
// this method is invoked once when web-application is undeployed (stopped) - here one can (should) implement resource cleanup etc
}
}
И затем, где-то в коде веб-приложения для доступа к dataSource
:
ServletContext servletContext = ...; // as mentioned above, it should be accessible from almost anywhere
DataSource dataSource = (DataSource) servletContext.getAttribute("some-data-source-alias");
// use dataSource
SomeDataSourceImpl
- это конкретная реализация javax.sql.DataSource. Пожалуйста, сообщите, если вы не используете конкретные dataSource
(например, ComboPooledDataSource для пула соединений) и не знаете, как его получить - Я опубликую, как обойти это.
some-data-source-alias
- это просто String
псевдоним (ключ) для вашего экземпляра dataSource
в таблице атрибутов ServletContext
. Хорошей практикой является предоставление псевдонимов с именем пакета, например com.mycompany.mywebapp.dataSource
.
Надеюсь, что это поможет...
Ответ 4
Если это Tomcat 7, вы можете написать свои собственные переменные чтения org.apache.tomcat.util.IntrospectionUtils.PropertySource
, написанные как "$ {...}" в context.xml
. Вам необходимо установить системное свойство org.apache.tomcat.util.digester.PROPERTY_SOURCE
, чтобы указать на реализацию PropertySource
.