Maven: настройка web.xml проекта веб-приложения - PullRequest
52 голосов
/ 21 июля 2010

У меня есть проект веб-приложения 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 ]

72 голосов
/ 21 июля 2010

есть ли способ иметь два файла 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>
        ...
44 голосов
/ 21 декабря 2011

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

21 голосов
/ 21 февраля 2013

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

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


${enable.security.start} -->

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

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


<!-- -->

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

19 голосов
/ 25 июля 2010

"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, это может оказаться подходящим вариантом для вас.

10 голосов
/ 09 октября 2014

Новая версия была добавлена ​​в 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>

Более подробная информация доступна в официальной документации по фильтрацииDeploymentDescriptors .

4 голосов
/ 24 ноября 2014

Улучшение до https://stackoverflow.com/a/3298876/2379360

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

<profiles>
    <profile>
        <id>profile1</id>
        <properties>
            <maven.war.webxml>path/to/custom/webXml</webXmlPath>
        </properties>
    </profile>
</profiles>
0 голосов
/ 25 сентября 2013
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>
...