将战争应用程序名称与战争文件名分开
Posted
技术标签:
【中文标题】将战争应用程序名称与战争文件名分开【英文标题】:Separating war application name from war file name 【发布时间】:2011-08-18 00:56:54 【问题描述】:目前,如果我在 tomcat 上部署一个名为 myapp.war
的 war 文件,我可以通过 http://localhost/myapp/MyServlet 访问其 url。
但是,我想要的是部署一个战争文件名中带有版本号的战争,并且仍然具有相同的 url。
例如,我想部署 myapp-1.1.0.war
并且仍然有 url 是 http://localhost/myapp/MyServlet
当然,我需要不断更新战争,版本号会不断变化,所以我不能在任何地方硬编码战争文件名。
web.xml
中是否有任何设置,无论战争文件名如何,我都可以使用它来为应用程序保留相同的 url?
【问题讨论】:
如果您只想在文件名中添加版本信息,请查看我对这个问题的回答:***.com/a/33822607/1458639 【参考方案1】:解决方法是停止使用Tomcat的自动部署功能,该功能采用将“上下文名称”(URL的/myapp
部分)设置为WAR文件名“.war”之前的部分的快捷方式。
相反,您可以自己将 WAR 内容提取到文件系统并在 TOMCAT_HOME/conf/[enginename]/[hostname]/[contextname].xml
处设置一个 XML 文件,该文件将所需的上下文路径(例如 /myapp
)指向磁盘上应用程序的位置(例如 /opt/webapps/myapp-1.1.0/
) .
Tomcat reference docs 很好地解释了 Tomcat 如何自动部署应用程序,以及如何配置自定义逻辑以将上下文路径映射到应用程序文件位置(除了我在上面建议的)。
【讨论】:
这是否意味着每次使用更新的文件名部署新版本的战争时,我也必须更新 .xml 文件? 我有点困惑。在这种情况下,“myapp.xml”文件的内容应该是什么才能使其指向战争的位置? 类似<Context docBase="/path/to/your/webapp/root" />
。 Tomcat 将使用不带.xml
扩展名的文件名作为上下文路径。另外关于我的符号链接建议,我刚刚在文档中注意到它指出 If a symbolic link is used for docBase then changes to the symbolic link will only be effective after a Tomcat restart or by undeploying and redeploying the context. A context reload is not sufficient.
【参考方案2】:
您可以为此使用 YOUR_WAR/META-INF/context.xml。这是一个示例:
<?xml version="1.0" encoding="UTF-8"?>
<Context antiJARLocking="true" path="/MyServlet"/>
【讨论】:
@Matthew Gillard 据我所知,tomcat 文档说不要在 Server.xml 中放置 Context 元素。他们对 META-INF/context.xml 没有任何问题。文档甚至告诉您 context.xml 是如何工作的。来自文档:“上下文元素可能被显式定义:* 在 $CATALINA_BASE/conf/context.xml 文件中:上下文元素信息将由所有 webapps 加载。” 那我是不是看错了? “路径”部分说:“除非在 server.xml 中静态定义上下文,否则不得设置此字段的值” 我认为tomcat 在这方面的行为(和文档!)非常令人困惑。尤其重要的是:如果您决定要更改 web 应用程序的上下文根目录,您必须手动从 $CATALINA_BASE/conf 中删除一个文件(该页面介绍部分的 5 个要点中的第 4 个) @Matthew Gillard 我唯一一次在让 META-INF/context.xml 做正确的事情时遇到困难是在我尝试设置根上下文时。在那种情况下,我发现我必须删除预先捆绑的根 webapp。除了它似乎工作正常。但是您是对的,文档/行为中似乎确实存在一些不一致之处。可能值得向他们提交票证?【参考方案3】:使用Maven 时,您可以通过执行以下操作来控制部署路径:
Tomcat 的 conf/tomcat-users.xml:
<tomcat-users>
<role rolename="manager-gui"/>
<role rolename="manager-script"/>
<role rolename="manager-jmx"/>
<role rolename="manager-status"/>
<role rolename="admin-gui"/>
<role rolename="admin-script"/>
<user username="root" password="root" roles="manager-gui,manager-script,manager-jmx,manager-status,admin-gui,admin-script"/>
</tomcat-users>
~/.m2/settings.xml:
...
<server>
<id>tomcat</id>
<username>root</username>
<password>root</password>
</server>
...
pom.xml:
...
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>myapp</artifactId>
<version>1.1.0</version>
<packaging>war</packaging>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<configuration>
<!-- neglect /html below Tomcat7: -->
<url>http://server:8080/manager/html</url>
<!-- Refer to the server settings in your ~/.m2/settings.xml -->
<server>tomcat</server>
<path>/myWebApp</path>
</configuration>
</plugin>
....
</plugins>
</build>
...
首先启动你的tomcat 然后构建并部署您的应用程序..
mvn clean install tomcat:deploy
..它可以在http://server:8080/myWebApp
下访问
【讨论】:
【参考方案4】:web.xml 中没有为此设置。我不相信有可能以跨容器的方式在 war 文件中设置它——无论如何在规范中都没有提到它——所以每个容器的做法都不同。 jboss-web.xml
、sun-web.xml
、context.xml
等
【讨论】:
因为我使用的是 wildfly 10,所以我在 jboss-web.xml 中对其进行了更改,它对我有用。【参考方案5】:我更喜欢使用“##”符号来标注 tomcat 中 *.war 文件的版本。
例如:myapp.war
-> URL:http://localhost:8080/myapp/MyServlet myapp##1.1.0
-> URL:http://localhost:8080/myapp/MyServlet(还是一样,因为“##”后面的所有符号都是被tomcat忽略)
【讨论】:
【参考方案6】:我遇到了同样的问题,事实上,正如@matt 提到的,Tomcat reference docs 很好地解释了 Tomcat 如何自动部署应用程序,以及如何配置自定义逻辑以将上下文路径映射到应用程序文件位置。
就我而言,我使用了这个建议(在“路径”解释中):
即使在 server.xml 中静态定义上下文时,此属性 (/path) 必须 not 设置,除非 docBase 不位于 主机的 appBase 或 deployOnStartup 和 autoDeploy 均为 false。如果 不遵守这条规则,很可能导致双重部署。
所以在我的情况下,我将 deployOnStartup
和 autoDeploy
都切换为 false,因此我的 WAR (egaWAR) 不会自动分解到 webapps 下的“a”目录,而是自动分解到“b”目录,因为到这些设置:
<Host name="localhost" appBase="webapps"
autoDeploy="false" deployOnStartup="false"
unpackWARs="true" deployIgnore="$ignore.context">
<Context docBase="a" path="/b" />
</Host>
【讨论】:
【参考方案7】:我发现关于这个主题的所有建议都有些简洁和混乱。以下方法适用于我使用默认的 tomcatee 安装。
假设我有一个名为 mywar.war 的战争文件。这包含一个到“/hello”的 servlet 映射。我想从 localhost:8080/myapp/hello 之类的 url 访问这个 servlet
此方法避免对 server.xml 进行任何不建议的更改,因为这需要重新启动 tomcat。
如果您部署到 /webapps,此方法将失败,因为它会尝试部署相同的战争两次。因此,我首先创建一个要部署到的新目录。我使用 /apps 但目录名称是任意的。
我现在将 mywar.war 复制到应用程序中。 Tomcat 忽略此操作。 我现在创建一个名为 myapp.xml 的简单部署文件。请注意,此文件的名称定义了将在其中部署战争的 URL 上下文。相信你可以使用 ROOT.xml 在 .内容如下:
如上所述,这需要复制到 /conf/Catalina/localhost 这会导致 tomcat 扩展和部署 /apps/mywar.war 并设置正确的 URL 上下文。 servlet 现在可以在 localhost://myapp/hello 上使用(或远程客户端的 :8080//myapp/hello)。
请注意,对于相对地址,docBase URL 标识 webapps 目录中战争的位置 - 因此前导 ..
【讨论】:
以上是关于将战争应用程序名称与战争文件名分开的主要内容,如果未能解决你的问题,请参考以下文章