从 .war 文件外部化 Tomcat webapp 配置

2024-10-28 08:37:00
admin
原创
278
摘要:问题描述:我在 Tomcat 7 中配置 webapp 时遇到了麻烦。在我的 WAR 文件中,有一个属性文件myApp/WEB-INF/classes/myProps.props,其中包含特定于环境的属性。我试图在服务器上覆盖该配置文件,以便将同一个 WAR 文件部署到多个环境。我听说有一种方法可以使用替换配...

问题描述:

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

我听说有一种方法可以使用替换配置文件来实现这一点tomcat/conf/Catalina/myApp。这是我很难弄清楚的方法。

此外,myApp.war它是运行在同一 Tomcat 服务器上的众多应用程序之一,并且不以本地主机身份运行。我希望能够为多个 Web 应用程序解决此问题。

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

解决方案 1:

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

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

举例来说,如果你的主机名为 name ,而你的应用程序是目录中myHost名为 name 的 war 文件,那么你可以使用如下内容创建:myApp.war`webapps`tomcat/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%)以获取该字符串值。

解决方案 2:

我喜欢.properties文件而不是

  • JNDI - 为什么在程序配置期间而不是初始化时构建复杂的对象?

  • 系统属性 - 您不能在单个 Tomcat 中分别配置同一个 WAR 的多个实例

  • 上下文参数 - 它们只能在 中访问javax.servlet.Filterjavax.servlet.ServletContextListener这可能会不方便

Tomcat 7上下文包含Loader元素。根据文档,部署描述符(<Context>标签中的 what)可以放置在:

  • $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}}'/>

参见:

  • 将目录添加到 tomcat 类路径

  • 我可以在 Tomcat 中根据每个应用程序创建自定义类路径吗

  • 如何在 Tomcat 中读取我的 webapp 上下文之外的属性文件

  • 配置 Tomcat 使用属性文件加载 DB 连接信息

  • 您是否应该在 server.xml 或 context.xml 中设置数据库连接属性

  • 外部化 Tomcat 配置

注意:通过将类路径扩展到实时目录,您还可以将任何其他配置(如日志记录、身份验证、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>

解决方案 3:

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

解决方案 4:

我刚刚在tomcat 文件夹中添加了一个setenv.batsetenv.sh脚本。设置变量如下bin`classpath`

set CLASSPATH=my-propery-folder
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2606  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1558  
  IPD(Integrated Product Development)流程作为一种先进的产品开发管理模式,在众多企业中得到了广泛应用。其中,技术评审与决策评审是IPD流程中至关重要的环节,它们既有明显的区别,又存在紧密的协同关系。深入理解这两者的区别与协同,对于企业有效实施IPD流程,提升产品开发效率与质量具有重要意义...
IPD管理流程   40  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、ClickUp、Freshdesk、GanttPRO、Planview、Smartsheet、Asana、Nifty、HubPlanner、Teamwork。在当今快速变化的商业环境中,项目管理软件已成为企业提升效率、优化资源分配和确保项目按时交付的关键工具。然而...
项目管理系统   38  
  建设工程项目质量关乎社会公众的生命财产安全,也影响着企业的声誉和可持续发展。高质量的建设工程不仅能为使用者提供舒适、安全的环境,还能提升城市形象,推动经济的健康发展。在实际的项目操作中,诸多因素会对工程质量产生影响,从规划设计到施工建设,再到后期的验收维护,每一个环节都至关重要。因此,探寻并运用有效的方法来提升建设工程...
工程项目管理制度   33  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用