Maven: настройка web.xml проекта веб-приложения

У меня есть проект веб-приложения Maven, и я хочу настроить файл web.xml в зависимости от запущенного профиля. Я использую плагин Maven-War, который позволяет мне определить каталог ресурсов, в котором файлы могут быть отфильтрованы. Однако одной фильтрации недостаточно для меня.

Более подробно, я хочу включить (или исключить) весь раздел по безопасности, в зависимости от профиля, который я запускаю. Это часть:

....
....

<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 и выбрать подходящий в зависимости от профиля?

7 ответов

Решение

Есть ли способ иметь два файла 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>
        ...

Есть третий компромиссный вариант, который я реализовал в своем проекте. Он хранит все в одном файле 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>
      ...

Таким образом, в основном, когда вы выбираете профиль для включения защиты, вы получаете два дополнительных CRLF в вашем файле web.xml. Когда вы выбираете профиль, который НЕ включает безопасность, XML все еще находится в файле web.xml, но он закомментирован, поэтому его игнорируют. Мне это нравится, потому что вам не нужно беспокоиться о синхронизации нескольких файлов, но XML по-прежнему доступен для чтения (и он находится в файле web.xml, где люди будут его искать).

Комментарий к ответу Криса Кларка. Вы можете повернуть вспять - поэтому в разработке вы не хотите иметь никаких ограничений (безопасность или jndi, другие)

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


${enable.security.start} -->

Итак, в разработке вы закомментировали раздел. Но в производстве это будет переведено на (с профилем maven):

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


<!-- -->

и закомментированный раздел будет виден.

"Matt B" уже опубликовал ответ, который является наиболее подходящим способом сделать это. Именно так я бы рекомендовал делать это в 99% случаев.

Однако иногда ваш файл конфигурации может быть довольно сложным, и нет смысла дублировать весь файл для каждой среды, когда отличается только одна строфа XML. В этих случаях вы можете использовать фильтрацию свойств для достижения своей цели.

Предупреждение, за ним следует очень скучное решение, и оно не для слабонервных:

В вашем pom.xml:

Внимание редакторам Stackru!!!!

Экранирование 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, это может подойти вам.

Новая версия была добавлена ​​в maven-war-plugin в версии 2.1-alpha-2. Его имя 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.

Улучшение /questions/23844136/maven-nastrojka-webxml-proekta-veb-prilozheniya/23844169#23844169

Вместо указания настраиваемого свойства используйте свойство по умолчанию maven.war.webxml в разных профилях.

<profiles>
    <profile>
        <id>profile1</id>
        <properties>
            <maven.war.webxml>path/to/custom/webXml</webXmlPath>
        </properties>
    </profile>
</profiles>
is there a way to have two web.xml files and select the appropriate one depending on the profile?

Помимо подхода, предложенного matt b, полезно подумать об этом иначе, главным образом потому, что во многих случаях вам придется связывать специфические конфигурации сервера приложений, которые не охватываются подключаемыми модулями maven (afaik). Они могут очень хорошо иметь различия между профилями.

В частности, вы можете использовать родительский проект, который имеет все общие файлы между веб-проектами разных профилей. Тогда у дочерних проектов могут быть разные файлы web.xml, а остальные идентификаторы делаются с помощью профилей и 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 имеет следующий пом

<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

<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>
Другие вопросы по тегам