在 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 并没有产生预期的结果
我还在Context
的path
属性的文档中找到了这一点:
除非在 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
的<Context>
元素的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 上下文的主要内容,如果未能解决你的问题,请参考以下文章
如何将 root(/) 上下文中的 war 文件部署到 Wildfly 9.0.1 版