web-dev-qa-db-fra.com

Maven: Personnalisez web.xml du projet d'application web

J'ai un projet d'application Web Maven et je souhaite personnaliser le fichier web.xml en fonction du profil en cours d'exécution. J'utilise le plugin Maven-War, qui me permet de définir un répertoire "ressources", où les fichiers peuvent être filtrés. Cependant, le filtrage seul ne me suffit pas.

Plus en détail, je veux inclure (ou exclure) toute la section sur la sécurité, selon le profil que j'exécute. C'est la partie:

....
....

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

....
....

Si cela ne se fait pas facilement, existe-t-il un moyen d'avoir deux fichiers web.xml et de sélectionner celui qui convient en fonction du profil?

52
Markos Fragkakis

existe-t-il un moyen d'avoir deux fichiers web.xml et de sélectionner celui qui convient en fonction du profil?

Oui, dans chaque profil, vous pouvez ajouter une configuration de maven-war-plugin et configurer chacun pour pointer vers un web.xml Différent.

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

Au lieu d'avoir à spécifier la configuration maven-war-plugin dans chaque profil, vous pouvez fournir une configuration par défaut dans la section principale du POM, puis la remplacer pour des profils spécifiques.

Ou pour être encore plus simple, dans le <build><plugins> Principal de votre POM, utilisez une propriété pour faire référence à l'attribut webXml, puis changez simplement sa valeur dans différents profils

<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>
        ...
73
matt b

Il y a une troisième option de compromis que j'ai implémentée dans mon projet. Il conserve tout dans un seul fichier web.xml tout en le rendant lisible ainsi que le fichier pom.xml. Dans mon cas, j'avais parfois besoin de sécurité et parfois pas de sécurité, selon l'environnement.

Donc ce que j'ai fait, c'est:

Dans le pom.xml, définissez deux profils (ou le nombre dont vous avez besoin). Dans les profils, incluez deux propriétés. Lorsque vous voulez de la sécurité, vous les laissez vides, comme ceci:

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

Lorsque vous souhaitez exclure toute la sécurité, vous les définissez comme suit:

<enable.security.start>&lt;!--</enable.security.start>
<enable.security.end>--&gt;</enable.security.end>

Ensuite, vous disposez d'un seul fichier web.xml avec les éléments suivants:

${enable.security.start}
<security-constraint>
  ...
  // all of the XML that you need, in a completely readable format
  ...
</login-config>  
${enable.security.end}

Le plugin pom.xml maven-war-plug doit être configuré pour utiliser le filtrage. Le mien ressemble à ceci:

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

Donc, fondamentalement, lorsque vous sélectionnez le profil pour inclure la sécurité, vous obtenez deux CRLF supplémentaires dans votre web.xml. Lorsque vous sélectionnez le profil pour NE PAS inclure la sécurité, le XML est toujours dans le web.xml, mais il est mis en commentaire afin qu'il soit ignoré. J'aime cela parce que vous n'avez pas à vous soucier de garder plusieurs fichiers synchronisés, mais le XML est toujours lisible (et il se trouve dans le fichier web.xml où les gens le chercheraient naturellement).

45
Chris Clark

Commentaire à Chris Clark réponse. Vous pouvez inverser - donc en développement, vous ne voulez pas avoir de contraintes (sécurité ou jndi, autre)

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


${enable.security.start} -->

Donc, dans le développement, vous avez commenté la section. Mais en production, il sera traduit (avec le profil maven):

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


<!-- -->

et la section commentée sera visible.

21
Andrzej Jozwik

"matt b" a déjà posté la réponse qui est la manière la plus maven de le faire. C'est la façon dont je recommanderais de le faire 99% du temps.

Cependant, parfois, votre fichier de configuration peut être assez compliqué, et il n'est pas très logique de dupliquer le fichier entier pour chaque environnement lorsqu'une seule strophe XML diffère. Dans ces cas, vous pouvez abuser du filtrage des propriétés pour atteindre votre objectif.

Attention, une solution très adhésive suit et ne sera pas pour les faibles de cœur:

Dans votre pom.xml:

Attention aux éditeurs StackOverflow !!!!

L'entité html qui s'échappe fait partie de la solution. La solution ne fonctionnera PAS si vous remplacez le tout par des signes supérieurs à et inférieurs à. Veuillez laisser la réponse telle quelle ...

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

dans votre web.xml

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

Étant donné que les propriétés inexistantes sont évaluées en une chaîne vide, vos configurations qui n'ont pas cette propriété définie (ou la propriété est une balise xml vide) seront évaluées en une ligne vide ici.

C'est moche, et le xml est difficile à modifier sous cette forme. Cependant, si votre fichier web.xml est complexe et que vous risquez davantage que 4 à 5 copies du fichier web.xml se désynchronisent, cela peut être une approche qui fonctionnera pour vous.

19
Brian M. Carr

Une nouvelle configuration a été ajoutée à maven-war-plugin dans la version 2.1-alpha-2. Son nom est filteringDeploymentDescriptors et il fait exactement ce que vous voulez.

Cela marche:

<plugin>
    <groupId>org.Apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.4</version>
    <configuration>
        <filteringDeploymentDescriptors>true</filteringDeploymentDescriptors>
    </configuration>
</plugin>

Et cela fonctionne aussi:

<properties>
    <maven.war.filteringDeploymentDescriptors>true</maven.war.filteringDeploymentDescriptors>
</properties>

Plus d'informations sont disponibles dans le documentation officielle de filteringDeploymentDescriptors .

10
Kristof Neirynck

Une amélioration de https://stackoverflow.com/a/3298876/237936

Au lieu de spécifier une propriété personnalisée, utilisez la propriété par défaut maven.war.webxml dans vos différents profils.

<profiles>
    <profile>
        <id>profile1</id>
        <properties>
            <maven.war.webxml>path/to/custom/webXml</maven.war.webxml>
        </properties>
    </profile>
</profiles>

De plus amples informations peuvent être trouvées sur le lien suivant: https://maven.Apache.org/plugins-archives/maven-war-plugin-2.4/war-mojo.html#webXml

4
tuckerpm
is there a way to have two web.xml files and select the appropriate one depending on the profile?

Outre l'approche suggérée par matt b, il est utile de penser l'inverse, principalement parce que dans de nombreux cas, vous devrez regrouper des configurations spécifiques au serveur d'applications qui ne sont pas couvertes par les plugins maven (afaik). Ceux-ci peuvent très bien avoir des différences entre les profils.

Plus précisément, vous pouvez utiliser un projet parent contenant tous les fichiers communs entre des projets Web de profils différents. Ensuite, les projets enfants peuvent avoir différents fichiers web.xml et l'id de reste fait avec les profils et le maven-war-plugin. Par exemple, j'ai utilisé cette disposition pour réaliser des builds sans assistance (autres que la spécification d'un profil) pour différents environnements cibles (développement, uat etc.)

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

Le pom de WebPc a le pom suivant

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

Et c'est le pom pour 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>
0
dkateros