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 и выбрать соответствующий в зависимости от профиля?
Ответы
Ответ 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, а затем просто переопределить его для определенных профилей.
Или, что еще проще, в основном <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>
...
Ответ 2
Есть третий, компромиссный вариант, который я реализовал в своем проекте. Он хранит все в одном 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}
Плагин mob-war-pom.xml должен быть настроен на использование фильтрации. Мой выглядит так:
<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, где люди, естественно, будут искать его).
Ответ 3
Комментарий Криса Кларка. Вы можете отменить - так что в разработке вы не хотите иметь никаких ограничений (безопасность или jndi, другие)
<!-- ${enable.security.end}
<security-constraint>
...
</security-constraint>
${enable.security.start} -->
Итак, в разработке вы закомментировали раздел. Но в производстве он будет переведен на (с профилем maven):
<!-- -->
<security-constraint>
...
</security-constraint>
<!-- -->
и комментарий будет виден.
Ответ 4
"matt b" уже отправил ответ, который является самым обычным способом. Именно так я бы рекомендовал делать это в 99% случаев.
Однако иногда ваш файл конфигурации может быть довольно сложным, и нет смысла дублировать весь файл для каждой среды, когда отличается только одна строфа XML. В этих случаях вы можете злоупотреблять фильтрацией свойств для достижения своей цели.
Предупреждение, из-за этого возникает очень проницаемое решение, и оно не будет для слабонервных:
В вашем pom.xml:
Внимание StackOverflow Editors!!!!
Вывод 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, выходящих из синхронизации, это может быть подход, который будет работать для вас.
Ответ 5
Новая версия была добавлена в 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.
Ответ 6
Улучшение fooobar.com/questions/111466/...
Вместо указания настраиваемого свойства используйте свойство по умолчанию 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
Ответ 7
is there a way to have two web.xml files and select the appropriate one depending on the profile?
Кроме подхода, предложенного матом b, полезно подумать об этом по-другому, главным образом потому, что во многих случаях вам придется связывать конкретные конфигурации сервера приложений, которые не покрываются плагинами maven (afaik). Они могут очень хорошо различать профили.
В частности, вы можете использовать родительский проект, который имеет все общие файлы между веб-проектами разных профилей. Тогда дочерние проекты могут иметь разные файлы 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
У pom WebPc есть следующая 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>
И это pom для 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>