55

我有一个 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 文件并根据配置文件选择合适的文件?

4

7 回答 7

78

有没有办法拥有两个 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 的主要部分提供默认配置,然后为特定配置文件覆盖它。

或者更简单地说,在<build><plugins>POM 的主要部分,使用属性来引用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>
        ...
于 2010-07-21T11:52:52.310 回答
48

我在项目中实施了第三种折衷方案。它将所有内容保存在一个 web.xml 中,同时仍然使其和 pom.xml 可读。就我而言,我有时需要有安全性,有时需要没有安全性,这取决于环境。

所以我所做的是:

在 pom.xml 中,定义两个配置文件(或任何您需要的配置文件)。在配置文件中,包括两个属性。当您需要安全性时,请将它们留空,如下所示:

<enable.security.start></enable.security.start>
<enable.security.end></enable.security.end>

当您想排除所有安全性时,您可以将它们定义如下:

<enable.security.start>&lt;!--</enable.security.start>
<enable.security.end>--&gt;</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 文件中,人们自然会在其中查找它)。

于 2011-12-21T16:26:50.297 回答
23

评论克里斯克拉克的回答。您可以反转 - 因此在开发中您不希望有任何限制(安全或 jndi,其他)

<!-- ${enable.security.end}
<security-constraint>
    ...
</security-constraint>


${enable.security.start} -->

所以在开发中你已经注释掉了部分。但在生产中,它将被翻译为(使用 Maven 配置文件):

<!-- -->
<security-constraint>
    ...
</security-constraint>


<!-- -->

和评论部分将可见。

于 2013-02-21T15:36:44.817 回答
19

“matt b”已经发布了最专业的答案。这是我建议 99% 的时间这样做的方式。

但是,有时,您的配置文件可能非常复杂,当只有一个 XML 节不同时,为每个环境复制整个文件没有多大意义。在这些情况下,您可以滥用属性过滤来实现您的目标。

警告,一个非常管道胶带的解决方案如下,并且不适合胆小的人:

在你的 pom.xml 中:

注意 StackOverflow 编辑器!!!!

html 实体转义是解决方案的一部分。如果您将其全部替换为大于和小于符号,则该解决方案将不起作用。请保持原样回答...

<properties>
    <test.security.config>
        &lt;security-constraint&gt;
            &lt;web-resource-collection&gt;
                &lt;web-resource-name&gt;protected&lt;/web-resource-name&gt;
                &lt;url-pattern&gt;/pages/*.xhtml&lt;/url-pattern&gt;
                &lt;url-pattern&gt;/pages/*.jsp&lt;/url-pattern&gt;
            &lt;/web-resource-collection&gt;

            &lt;auth-constraint&gt;
                &lt;role-name&gt;*&lt;/role-name&gt;
            &lt;/auth-constraint&gt;

            &lt;/security-constraint&gt;
                &lt;login-config&gt;
                &lt;auth-method&gt;${web.modules.auth.type}&lt;/auth-method&gt;
                &lt;realm-name&gt;MyRealm&lt;/realm-name&gt;
            &lt;/login-config&gt;

        &lt;security-constraint&gt;
    </test.security.config>
</properties>

在你的 web.xml

....
${test.security.config}
....

因为不存在的属性评估为空字符串,所以没有设置此属性(或属性是空 xml 标记)的配置将在此处评估为空行。

很丑,这种形式的xml很难修改。但是,如果您的 web.xml 很复杂,并且存在 4-5 个 web.xml 副本不同步的更大风险,那么这可能是一种适合您的方法。

于 2010-07-25T00:51:50.557 回答
12

在 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>

更多信息可以在filteringDeploymentDescriptors 的官方文档中找到。

于 2014-10-09T14:38:55.540 回答
4

https://stackoverflow.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

于 2014-11-24T13:30:49.623 回答
0
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>
于 2013-09-25T14:31:09.900 回答