39

我在 Tomcat 7 中配置 webapp 时遇到问题。在我的 WAR 文件中,有一个属性文件myApp/WEB-INF/classes/myProps.props,它包含特定于环境的属性。我正在尝试覆盖服务器上的该配置文件,以便将同一个 WAR 文件部署到多个环境。

我听说有一种方法可以使用tomcat/conf/Catalina/myApp. 这是我无法弄清楚的方法。

此外,myApp.war它是在同一 Tomcat 服务器上运行的众多服务器之一,并且它不作为 localhost 运行。我希望能够为几个 webapps 解决这个问题。

Server version: Apache Tomcat/7.0.23
Server built:   Nov 20 2011 07:36:25
Server number:  7.0.23.0
OS Name:        Linux
4

4 回答 4

68

tomcat/conf/Catalina/<host>可以包含上下文描述符,让您可以配置很多东西,包括定义“环境条目”,这些可以通过 JNDI 从 Java 访问。有很多方法可以使用它。就个人而言,我设置了一个环境条目,它是我的属性文件的文件系统路径。我的应用程序是为检查此条目而构建的,如果它不存在,则改为在类路径中查找该文件。这样,在 dev 中,我们在类路径中就有了 dev 属性,但是当我们构建和部署时,我们将它指向一个外部文件。

在 Tomcat 网站上有很好的配置上下文的文档。有关如何创建文件以及将其放置在何处的详细信息,请参阅定义上下文部分。

例如,如果您的主机被命名并且您的应用程序是目录中命名的myHostwar 文件,那么您可以使用以下内容创建:myApp.warwebappstomcat/conf/Catalina/myHost/myApp.xml

<Context>
    <Environment name="configurationPath" value="/home/tomcat/myApp.properties" type="java.lang.String"/>
</Context>

然后从您的代码中,您将执行 JNDI 查找java:comp/env/configurationPath(此处为 95% 确定性)以获取该字符串值。

于 2012-12-21T23:43:54.000 回答
48

我喜欢.properties文件而不是

  • JNDI - 为什么在程序配置而不是初始化时构建复杂对象?
  • 系统属性 - 您不能在单个 Tomcat 中单独配置相同 WAR 的多个实例
  • 上下文参数 - 它们只能在 中访问javax.servlet.Filterjavax.servlet.ServletContextListener这很不方便

Tomcat 7 Context包含 Loader元素。根据文档部署描述符(<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 将上述属性注入 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}}'/>

也可以看看:

注意通过将类路径扩展到实时目录,您还允许外部化任何其他配置,例如日志记录、身份验证、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>
于 2014-10-01T17:09:04.583 回答
1

您可以尝试将配置(属性文件)放在 JAR 文件中的 Apache Tomcat\lib 中,然后将其从 Web 应用程序中删除。当 Tomcat 的类加载器在 webapp 中找不到您的配置时,它会尝试在“lib”目录中查找。因此,您可以将您的配置外部化,只需将配置移动到全局 lib 目录(它在其他 webapps 之间共享)。

于 2012-12-22T13:54:02.977 回答
0

我只是在tomcat的文件夹中添加了一个setenv.batorsetenv.sh脚本。bin像这样设置classpath变量

set CLASSPATH=my-propery-folder
于 2017-07-06T11:49:20.287 回答