如何在Tomcat中为Web应用程序提供上下文配置?

2022-08-31 21:01:07

我有一个Web应用程序,它依赖于一些资源和参数在安装后进行配置,例如JDBC连接。

我想到的是提供一个在我部署应用程序时由Tomcat复制到其中的。这样,我提供的只是一个可以复制到appBase文件夹(webapps)中的war文件。Tomcat的文档,如果有这样的文件,它不会被覆盖,这真的很棒,因为部署后所做的更改不会丢失。META-INF/context.xml[engine-name]/[server-name]/[app-name].xml

但是这里有一个微妙的问题:由于我们通过复制到webapps目录来部署应用程序,因此Tomcat将首先卸载现有的应用程序以及配置文件。这样,配置文件将丢失/覆盖,这是不可取的。据我所知,Tomcat不会改变这种行为。

问题是:有没有办法通过以Tomcat不会删除现有配置文件的方式安装应用程序来解决此问题。或者,有没有更好的方法来打包应用程序?

请注意,我们不希望将自动部署设置为 false,并且我们不能对安装使用人为干预(这排除了使用 Tomcat Manager Web 应用程序的可能性)。

如果我从.war文件中获取配置文件并将其单独复制为,Tomcat仍将它与我的应用程序相关联,并在我复制新的.war文件后将其删除。[engine-name]/[server-name]/[app-name].xml

另一个假设是:我们事先不知道配置的值。我们只会提供一个示例配置(如果您愿意,可以提供占位符),而实际配置将在稍后的某个时间执行(不一定在安装时间)。

谢谢


答案 1

解决方案很简单:不要将配置放在上下文中.xml。

以下是我们使用的解决方案(适用于许多不同的外部客户):

我们有一场将在多个环境中使用的战争,webapp.war。我们有三个环境,开发,集成和生产。集成和生产在客户现场进行。我们不知道客户端集成和生产站点的密码和文件路径。

我们使用两种东西的组合:JNDI查找数据库内容和外部属性文件。

上下文中.xml在战争中交付,我们有一个资源链接

<ResourceLink name="jdbc/webapp"
     global="uk.co.farwell.webapp.datasource.MySqlDataSource" />

这给出了对全局定义的数据源的引用,该数据源在服务器中定义.xml为Tomcat。

<Resource auth="Container" 
          driverClassName="com.mysql.jdbc.Driver" 
          name="uk.co.farwell.webapp.datasource.MySqlDataSource" 
          password="xxx" url="xxx" username="fff" />

因此,可以通过编辑而不更改 .至关重要的是,这只需要为每个服务器执行一次,而无需重新部署。server.xmlwebapp.war

在我们的弹簧配置中,定义我们有:dataSource

<jee:jndi-lookup id="dataSource" jndi-name="jdbc/webapp" />

对于其他属性,我们有一个全局 application.properties 文件,它与 webapp.war 一起提供,但不是战争的一部分。这由 命令行上的 引用 以启动 Tomcat。.我们选取定义并读取属性文件。数据库的东西也可以通过这种方式完成,但是我们会失去Tomcat完成的池化。-D-Duk.co.farwell.webapp.applicationDir="/usr/xxx/fff"

另一件事:如果服务器被移动,或者如果机器由于某种原因被改变,我们不必重建。这是客户及其基础架构人员的问题。


答案 2

我设法以某种方式解决了这个问题。

1-在Tomcat的appBase之外的某个地方安装一个分解的WAR目录,让我们假设它位于.[如果您的应用程序在未爆炸的战争中运行,则可以在此步骤中使用 WAR 文件而不是 WAR 目录。/usr/local/MyApp

2-将上下文配置文件复制到目录中,我们称之为.此文件将指向应用程序的位置:[tomcat.conf]/[engine]/[hostname]MyApp.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- Context configuration file for my web application -->
<Context docBase="/usr/local/MyApp" privileged="true" antiResourceLocking="false" antiJARLocking="false">
        <Resource name="jdbc/myapp-ds" auth="Container" type="javax.sql.DataSource"
                maxActive="100" maxIdle="30" maxWait="10000" username="XXX" password="XXX"
                driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/mydb" />
</Context>

3-您现在可以自由地修改配置文件。

4-通过在/usr/local/MyApp中复制应用程序的新版本来更新应用程序

笔记:

a)此解决方案也适用于未展开的.war文件,但由于我们使用Spring的Log4JConfigListener,因此它不会从未展开的.war文件运行。Tomcat 不会分解放置在 appBase(webapps)文件夹外的 .war 文件。

b) 这种方法不会阻止你在 /usr/local/MyApp/META-INF/context 中拥有上下文.xml.xml因为 Tomcat 不会在此配置中使用它。可以在开发环境中使用它,在开发环境中,将 .war 文件转储到 appBase(webapps)文件夹中。

这就是我到目前为止所得到的,仍然在寻找更好的解决方案。


推荐