我在Tomcat 7中配置webapp时遇到问题。在我的WAR文件中,有一个属性文件myApp/WEB-INF/classes/myProps.props
,它包含特定于环境的属性。我试图覆盖服务器上的配置文件,以便相同的WAR文件将部署到多个环境。
我听说有一种方法可以使用tomcat/conf/Catalina/myApp
中的替换配置文件来完成此操作。这是我无法搞清楚的方法。
此外,myApp.war
是在同一个Tomcat服务器上运行的许多服务器之一,并且它不作为localhost运行。我希望能够为几个webapp解决这个问题。
Server version: Apache Tomcat/7.0.23
Server built: Nov 20 2011 07:36:25
Server number: 7.0.23.0
OS Name: Linux
答案 0 :(得分:63)
您的tomcat/conf/Catalina/<host>
可以包含允许您配置许多内容的上下文描述符,包括定义“环境条目”,这些条目可以通过JNDI从Java访问。有很多方法可以使用它。就个人而言,我设置了一个环境条目,它是我的属性文件的文件系统路径。我的应用程序是为检查此条目而构建的,如果它不存在,请在类路径中查找该文件。这样,在开发中,我们在类路径上有dev属性,但是当我们构建和部署时,我们将它指向外部文件。
Tomcat网站上有configuring a context的好文档。有关如何创建文件以及放置文件的详细信息,请参阅Defining a Context section。
例如,如果您的主机名为myHost
且您的应用是myApp.war
目录中名为webapps
的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%确定)以获取该字符串值。
答案 1 :(得分:43)
我喜欢.properties
个文件而不是
javax.servlet.Filter
,javax.servlet.ServletContextListener
中访问,我不方便 Tomcat 7 Context持有Loader元素。根据{{3}}部署描述符(<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
docs(在现代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将以上属性注入bean字段很容易:
@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}}'/>
另见:
注意通过将类路径扩展到实时目录,您还允许外部化任何其他配置,例如logging,auth,atc。我以这种方式对logback.xml
进行了外部化。
更新 Externalize Tomcat configuration <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>
答案 2 :(得分:1)
您可以尝试将配置(属性文件)放在JAR文件的Apache Tomcat \ lib中,并将其从Web应用程序中删除。当Tomcat的类加载器在webapp中找不到您的配置时,它将尝试在“lib”目录中查找。因此,您可以将配置外部化,只需将配置移动到全局lib目录(它与其他Web应用程序共享)。
答案 3 :(得分:0)
我刚刚在tomcat的setenv.sh
文件夹中添加了bin
或classpath
脚本。将set CLASSPATH=my-propery-folder
变量设置为
<ReactTable
data={ tableData }
columns={ tableColumns }
showPagination={ false }
defaultPageSize={ tableData.length }
/>