Maven:自定义 web-app 项目的 web.xml
Posted
技术标签:
【中文标题】Maven:自定义 web-app 项目的 web.xml【英文标题】:Maven: Customize web.xml of web-app project 【发布时间】:2011-03-18 22:41:39 【问题描述】:我有一个 Web 应用程序 Maven 项目,我想根据正在运行的配置文件自定义 web.xml 文件。我正在使用 Maven-War-plugin,它允许我定义一个“资源”目录,可以在其中过滤文件。但是,仅过滤对我来说是不够的。
更详细地说,我想包括(或排除)整个安全部分,具体取决于我正在运行的配置文件。这是部分:
....
....
<security-constraint>
<web-resource-collection>
<web-resource-name>protected</web-resource-name>
<url-pattern>/pages/*.xhtml</url-pattern>
<url-pattern>/pages/*.jsp</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>$web.modules.auth.type</auth-method>
<realm-name>MyRealm</realm-name>
</login-config>
<security-constraint>
....
....
如果这不容易做到,有没有办法拥有两个 web.xml 文件并根据配置文件选择合适的文件?
【问题讨论】:
【参考方案1】:有没有办法拥有两个 web.xml 文件并根据配置文件选择合适的文件?
是的,您可以在每个配置文件中添加maven-war-plugin
的配置,并将每个配置文件配置为指向不同的web.xml
。
<profiles>
<profile>
<id>profile1</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webXml>/path/to/webXml1</webXml>
</configuration>
</plugin>
...
作为必须在每个配置文件中指定 maven-war-plugin
配置的替代方法,您可以在 POM 的主要部分提供默认配置,然后为特定配置文件覆盖它。
或者更简单,在 POM 的主要 <build><plugins>
中,使用属性来引用 webXml
属性,然后在不同的配置文件中更改它的值
<properties>
<webXmlPath>path/to/default/webXml</webXmlPath>
</properties>
<profiles>
<profile>
<id>profile1</id>
<properties>
<webXmlPath>path/to/custom/webXml</webXmlPath>
</properties>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webXml>$webXmlPath</webXml>
</configuration>
</plugin>
...
【讨论】:
【参考方案2】:“matt b”已经发布了最专业的答案。这是我建议 99% 的时间这样做的方式。
但是,有时,您的配置文件可能非常复杂,当只有一个 XML 节不同时,为每个环境复制整个文件没有多大意义。在这些情况下,您可以滥用属性过滤来实现您的目标。
警告,下面是一个非常胶带式的解决方案,不适合胆小的人:
在你的 pom.xml 中:
注意 *** 编辑器!!!!
html 实体转义是解决方案的一部分。该解决方案将 如果你用大于号和小于号替换它就不行了。 请按原样保留答案...
<properties>
<test.security.config>
<security-constraint>
<web-resource-collection>
<web-resource-name>protected</web-resource-name>
<url-pattern>/pages/*.xhtml</url-pattern>
<url-pattern>/pages/*.jsp</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>$web.modules.auth.type</auth-method>
<realm-name>MyRealm</realm-name>
</login-config>
<security-constraint>
</test.security.config>
</properties>
在您的 web.xml 中
....
$test.security.config
....
由于不存在的属性评估为空字符串,因此未设置此属性(或属性为空 xml 标记)的配置将在此处评估为空行。
很丑,这种形式的xml很难修改。但是,如果您的 web.xml 很复杂,并且存在 4-5 个 web.xml 副本不同步的更大风险,那么这可能是一种适合您的方法。
【讨论】:
我其实更喜欢这种方式。它并不难看,并且使用不同的 web.xml 文件,我可以看到有人对开发 web.xml 进行了更改,并且它工作,然后使用生产的 web.xml 构建,部署,并且站点关闭了。 我必须将属性包装在 中才能使其正常工作。 因为人们一直在帮助编辑原件(提示,> 是解决方案的一部分!!!!),请注意,上述内容不能开箱即用。我已经修复了它,但人们不断将它改回来...... 在构建 EAR 时可以使用此解决方案吗?假设我有一个包含两个 EAR 子项目的 maven 项目,每个项目都包含相同的 WAR,但需要不同的 web.xml。web-fragment.xml
不适用于 EAR/lib 打包。见***.com/questions/48390170/…【参考方案3】:
我在项目中实施了第三种折衷方案。它将所有内容保存在一个 web.xml 中,同时仍然使其和 pom.xml 可读。就我而言,我有时需要有安全性,有时需要没有安全性,具体取决于环境。
所以我做的是:
在 pom.xml 中,定义两个配置文件(或者您需要的任意多个)。在配置文件中,包括两个属性。当您需要安全性时,您可以将它们留空,如下所示:
<enable.security.start></enable.security.start>
<enable.security.end></enable.security.end>
当你想排除所有的安全性时,你定义它们如下:
<enable.security.start><!--</enable.security.start>
<enable.security.end>--></enable.security.end>
然后,您有一个 web.xml 文件,其中包含以下内容:
$enable.security.start
<security-constraint>
...
// all of the XML that you need, in a completely readable format
...
</login-config>
$enable.security.end
必须将 pom.xml maven-war-plugin 配置为使用过滤。我的看起来像这样:
<configuration>
<webResources>
<resource>
<filtering>true</filtering>
<directory>src/main/webapp</directory>
<includes>
<include>**/web.xml</include>
</includes>
</resource>
</webResources>
<warSourceDirectory>src/main/webapp</warSourceDirectory>
<webXml>src/main/webapp/WEB-INF/web.xml</webXml>
...
因此,基本上,当您选择包含安全性的配置文件时,您会在 web.xml 中获得两个额外的 CRLF。当您选择不包含安全性的配置文件时,XML 仍然在 web.xml 中,但它已被注释掉,因此被忽略。我喜欢这样,因为您不必担心保持多个文件同步,但 XML 仍然是可读的(并且它位于 web.xml 文件中,人们自然会在其中查找它)。
【讨论】:
我使用了类似的技术。我没有使用注释开始和结束节点,而是创建了一个注释宏,例如评论Chris Clark 答案。您可以反转 - 因此在开发中您不希望有任何约束(安全或 jndi,其他)
<!-- $enable.security.end
<security-constraint>
...
</security-constraint>
$enable.security.start -->
所以在开发中你已经注释掉了部分。但在生产中,它将被翻译成(使用 maven 配置文件):
<!-- -->
<security-constraint>
...
</security-constraint>
<!-- -->
评论部分将可见。
【讨论】:
【参考方案5】:is there a way to have two web.xml files and select the appropriate one depending on the profile?
除了 matt b 建议的方法之外,反过来考虑它是有用的,主要是因为在许多情况下,您将不得不捆绑 maven 插件 (afaik) 未涵盖的应用程序服务器特定配置。这些很可能在配置文件之间存在差异。
具体来说,您可以使用包含不同配置文件的 Web 项目之间的所有公共文件的父项目。然后子项目可以有不同的 web.xml 文件,其余的 id 用配置文件和maven-war-plugin
完成。例如,我已使用此布局为不同的目标环境(开发、uat 等)实现无人参与的构建(除了指定配置文件)
WebPc
├── common
│ ├── css
│ ├── images
│ ├── js
│ └── WEB-INF
│ └──├── wsdl
│── pom.xml
│
├── WebPc-DEV
│ ├── pom.xml
│ └── src
│ └── main
│ └── webapp
│ └── WEB-INF
│ ├── geronimo-web.xml
│ ├── ibm-web-bnd.xml
│ ├── ibm-web-ext.xml
│ └── web.xml
├── WebPc-UAT
│ ├── pom.xml
│ └── src
│ └── main
│ └── webapp
│ └── WEB-INF
│ ├── geronimo-web.xml
│ ├── ibm-web-bnd.xml
│ ├── ibm-web-ext.xml
│ └── web.xml
WebPc的pom有以下pom
<groupId>my.grp</groupId>
<artifactId>WebPc</artifactId>
<packaging>pom</packaging>
<profiles>
<profile>
<id>DEV</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<modules>
<module>WebPc-DEV</module>
</modules>
</profile>
<profile>
<id>UAT</id>
<modules>
<module>WebPc-UAT</module>
</modules>
</profile>
</profiles>
<build>
<pluginManagement>
<plugins>
<!-- copy common resources located on parent
project common folder for packaging -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<resourceEncoding>$project.build.sourceEncoding</resourceEncoding>
<webResources>
<resource>
<directory>../common</directory>
<excludes>
<exclude>WEB-INF/**</exclude>
</excludes>
</resource>
<resource>
<directory>../common/WEB-INF</directory>
<includes>
<include>wsdl/*.wsdl</include>
<include>wsdl/*.xsd</include>
</includes>
<targetPath>WEB-INF</targetPath>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
这是 WebPc-DEV 的 pom
<parent>
<groupId>my.grp</groupId>
<artifactId>WebPc</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>WebPc-DEV</artifactId>
<packaging>war</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
</plugin>
</plugins>
</build>
【讨论】:
【参考方案6】:在 2.1-alpha-2 版本中向 maven-war-plugin 添加了新配置。
它的名字是filteringDeploymentDescriptors
,它完全符合您的要求。
这行得通:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<filteringDeploymentDescriptors>true</filteringDeploymentDescriptors>
</configuration>
</plugin>
这也有效:
<properties>
<maven.war.filteringDeploymentDescriptors>true</maven.war.filteringDeploymentDescriptors>
</properties>
更多信息请访问official documentation of filteringDeploymentDescriptors。
【讨论】:
【参考方案7】:对https://***.com/a/3298876/2379360的改进
不要指定自定义属性,而是在不同的配置文件中使用默认属性 maven.war.webxml。
<profiles>
<profile>
<id>profile1</id>
<properties>
<maven.war.webxml>path/to/custom/webXml</maven.war.webxml>
</properties>
</profile>
</profiles>
更多信息可以在以下链接中找到:https://maven.apache.org/plugins-archives/maven-war-plugin-2.4/war-mojo.html#webXml
【讨论】:
是maven.war.webxml还是webXmlPath?您的开始标签与结束标签不同。以上是关于Maven:自定义 web-app 项目的 web.xml的主要内容,如果未能解决你的问题,请参考以下文章
maven web.xml 元素类型“web-app”必须由匹配的结束标签“</web-app>”终止
Maven02_04_使用jetty来跑maven的web项目使用jetty的注意事项没有用Maven的时候是怎么打包的,自定义打包的名字的