在 WAR 文件中定义 Servlet 上下文

Posted

技术标签:

【中文标题】在 WAR 文件中定义 Servlet 上下文【英文标题】:Define Servlet Context in WAR-File 【发布时间】:2011-02-05 07:31:55 【问题描述】:

我怎么知道例如Tomcat 在给定我的 WAR 文件时使用特定的上下文路径?

示例: 我有一个由 maven build 创建的战争文件,文件的结果名称相当长。 所以我不希望tomcat管理器应用程序使用war的文件名作为上下文。

在 META-INF 中提供 context.xml 并没有产生预期的结果

我还在Contextpath 属性的文档中找到了这一点:

除非在 server.xml 中静态定义上下文,否则不得设置此字段的值,因为它将从用于 .xml 上下文文件或 docBase 的文件名中推断出来。

因此,告诉应用程序服务器我的 WAR 路径应该是什么似乎不是正确的方法。

还有什么提示吗?

【问题讨论】:

【参考方案1】:

Context Container的文档中有两个重点:

$CATALINA_BASE/conf/[enginename]/[hostname]/ 目录中的单个文件(扩展名为“.xml”)中。 文件名(减去 .xml 扩展名)将用作上下文路径。可以使用 # 定义多级上下文路径,例如foo#bar.xml 用于 /foo/bar 的上下文路径。可以使用名为 ROOT.xml 的文件来定义默认 Web 应用程序。 仅当在$CATALINA_BASE/conf/[enginename]/[hostname]/ 中不存在应用程序的上下文文件时,在应用程序文件内/META-INF/context.xml 的单个文件中。 如果 Web 应用程序打包为 WAR,则 /META-INF/context.xml 将被复制到 $CATALINA_BASE/conf/[enginename]/[hostname]/ 并重命名以匹配应用程序的上下文路径。此文件一旦存在,如果将具有较新 /META-INF/context.xml 的新 WAR 放置在主机的 appBase 中,它将不会被替换。

因此,当您捆绑 META-INF/context.xml 时,文件将重命名为 WAR 的名称,并且此名称成为上下文路径,而不管 Context 元素中定义的任何 path

我在这里看到两个选项:

    将生成的战争的名称设置为更短的名称(我建议使用 <finalName> 而不是 <warName>,这是不推荐使用的 AFAIK):

    <project>
      ...
      <build>
        <finalName>mycontext</finalName>
        ...
      </build>
      ...
    </project>
    

    或者使用maven-tomcat-plugin进行部署并在插件配置中设置上下文路径:

    <project>
      ...
      <build>
        ...
        <plugins>
          ...
          <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>tomcat-maven-plugin</artifactId>
            <version>1.0-SNAPSHOT</version>
            <configuration>
              <path>/mycontext</path>
            </configuration>
          </plugin>
          ...
        </plugins>
        ...
      </build>
      ...
    </project>
    

【讨论】:

感谢 sn-p。下面这句话对我的东西很重要。添加到 context.xml 文件本身的注释/引用作为对下一个开发人员的警告。 “一旦这个文件存在,如果在宿主的appBase中放置了一个新的/META-INF/context.xml的WAR,它将不会被替换。”【参考方案2】:

我找到了一个简单的解决方案来保留战争文件名并选择上下文路径。

您只需将您的战争部署到主机的appBase 之外并在appBase 目录内创建一个链接。

例如。 :

ln -sf $CATALINA_HOME/wars/myapp-0.0.8-SNAPSHOT.war $CATALINA_HOME/webapps/myapp.war

埃克托

【讨论】:

符号链接通过简单地更改符号链接提供了快速回滚的额外好处。 这个解决方案也有助于自动化java.dzone.com/articles/super-quick-tomcat-app【参考方案3】:

您可以设置META-INF/context.xml&lt;Context&gt; 元素的path 属性。

或者,您可以配置 maven 以使用自定义名称创建战争工件:

<build>
    <plugins>
         <plugin>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.0</version>
            <configuration>
                <warName>yourCustomWarName</warName>
            </configuration>
        </plugin>
        ........
    </plugins>
</build>

【讨论】:

很抱歉,这里的记录被打破了,但设置路径实际上在 Tomcat 中不起作用(在 6.0.28 上测试),如上面 Pascal 所述。 我不赞成第一句话,因为它根本不正确,上下文路径来自 WAR 文件名,但其余答案很好 @chrisbunney 上下文路径默认来自war文件名,但可以覆盖 也许你能详细说明一下?我所有的调查都让我相信 path 属性被忽略了,除非在 server.xml 中定义了 Context 元素,而且我还没有找到任何方法来改变这种行为 如果您处于自动部署模式,则不能覆盖由战争名称定义的上下文路径【参考方案4】:

在您的项目中有一个 META-INF 文件夹,在该文件夹中有一个 context.xml 文件。

<?xml version="1.0" encoding="UTF-8"?>
<Context  path="/myproject" />

【讨论】:

我想用这个方法,但是当tomcat解压我的war时,它会创建一个与war同名的文件夹,并在/opt/apache-tomcat-中创建一个.xml文件6.0.29/conf/Catalina/localhost/,这是你提到的定义的 context.xml 的副本。你明白为什么吗? 我同意 - 由于 Pascal 所描述的原因,这种方法在 Tomcat 6.0.28 中肯定行不通 我从来没有能够让这种方法起作用,而且我看到的文档确实表明 path 属性仅在 server.xml 中设置上下文时使用(否则它是从文件名) 如果您处于自动部署模式,则不能覆盖由战争名称定义的上下文路径

以上是关于在 WAR 文件中定义 Servlet 上下文的主要内容,如果未能解决你的问题,请参考以下文章

Spring分层上下文

如何将 root(/) 上下文中的 war 文件部署到 Wildfly 9.0.1 版

过滤器监听器上下文servlet线程安全问题

如何在 servlet 上下文中从 jar 文件中读取 xml 模式

Web应用部署

多个应用程序上下文,多个调度程序 servlet?