我在Tomcat 7中配置Web应用程序时遇到问题。在我的WAR文件中,有一个属性文件myApp/WEB-INF/classes/myProps.props
,它包含特定于环境的属性。我正在尝试覆盖服务器上的该配置文件,以便将相同的 WAR 文件部署到多个环境。
我听说有一种方法可以使用tomcat/conf/Catalina/myApp
中的替换配置文件来做到这一点。这是我无法弄清楚的方法。
此外,myApp.war
是在同一Tomcat服务器上运行的众多服务器之一,它不作为本地主机运行。我希望能够为几个网络应用程序解决此问题。
Server version: Apache Tomcat/7.0.23
Server built: Nov 20 2011 07:36:25
Server number: 7.0.23.0
OS Name: Linux
您的tomcat/conf/Catalina/<host>
可以包含上下文描述符,这些描述符允许您配置许多内容,包括定义"环境条目",这些条目可以通过 JNDI 从 Java 访问。有很多方法可以使用它。就个人而言,我设置了一个环境条目,它是我的属性文件的文件系统路径。我的应用程序是为了检查此条目而构建的,如果它不存在,请改为在类路径上查找该文件。这样,在 dev 中,我们在类路径上就有 dev 属性,但是当我们构建和部署时,我们会将其指向外部文件。
Tomcat 网站上有关于配置上下文的良好文档。请参阅定义上下文部分,详细了解如何创建文件以及放置文件的位置。
例如,如果您的主机名为myHost
,并且您的应用程序是webapps
目录中名为myApp.war
的战争文件,则可以使用以下内容创建tomcat/conf/Catalina/myHost/myApp.xml
:
<Context>
<Environment name="configurationPath" value="/home/tomcat/myApp.properties" type="java.lang.String"/>
</Context>
然后从您的代码中,您将对java:comp/env/configurationPath
进行 JNDI 查找(此处为 95% 的确定性)以获取该字符串值。
我喜欢.properties
文件而不是
- JNDI - 为什么要在程序配置期间而不是初始化时构建复杂对象?
- 系统属性 - 不能在单个 Tomcat 中单独配置同一 WAR 的多个实例
- 上下文参数 - 它们只能在
javax.servlet.Filter
中访问,javax.servlet.ServletContextListener
我不方便
Tomcat 7 上下文保存加载器元素。根据文档部署描述符(<Context>
标签中的内容)可以放置在:
$CATALINA_BASE/conf/server.xml
- 坏 - 需要重新启动服务器才能重新读取配置$CATALINA_BASE/conf/context.xml
- 坏 - 在所有应用程序之间共享$CATALINA_BASE/work/$APP.war:/META-INF/context.xml
- 不好 - 需要重新打包才能更改配置$CATALINA_BASE/work/[enginename]/[hostname]/$APP/META-INF/context.xml
-不错,但请参阅最后一个选项!$CATALINA_BASE/webapps/$APP/META-INF/context.xml
-不错,但看到最后一个选项!$CATALINA_BASE/conf/[enginename]/[hostname]/$APP.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")
访问):
<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>
如果你使用Spring并且它是XML配置:
<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>
使用Spring,将上述属性注入豆田很容易:
@Value("${db.user}") String defaultSchema;
而不是 JNDI:
@Inject ApplicationContext context;
Enviroment env = context.getEnvironment();
String defaultSchema = env.getProperty("db.user");
另请注意,EL 允许这样做(默认值和深度递归替换):
@Value('${db.user:testdb}') private String dbUserName;
<property name='username' value='${db.user.${env}}'/>
另请参阅:
- 将目录添加到 tomcat 类路径
- 我可以在 Tomcat 中基于每个应用程序创建自定义类路径吗
- 如何在 Tomcat 中读取我的 Web 应用程序上下文之外的属性文件
- 配置 Tomcat 以使用属性文件加载数据库连接信息
- 应在服务器.xml或上下文中设置数据库连接属性.xml
- 外部化雄猫配置
注意:通过将类路径扩展到活动目录,您还可以排除任何其他配置,例如日志记录,身份验证,atc。我以这种方式驱逐logback.xml
。
更新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>
您可以尝试将配置(属性文件)放在 Apache Tomcat\lib 中的 JAR 文件中,并将其从 Web 应用程序中删除。当 Tomcat 的类加载器在 webapp 中找不到您的配置时,它将尝试在"lib"目录中查找。因此,您只需将配置移动到全局 lib dir(在其他 Web 应用程序之间共享)即可外部化配置。
我只是在 tomcat 的bin
文件夹中添加了一个setenv.bat
或setenv.sh
脚本。像这样设置classpath
变量
set CLASSPATH=my-propery-folder