简体   繁体   中英

How to modify the contents or replace a file which resides in webapp directory of a Maven webapp project

I've a Maven webapp project. It has a default directory structure as below -

 |-- pom.xml
 `-- src
     `-- main
         |-- java
         |   `-- com
         |       `-- example
         |           `-- projects
         |               `-- SampleAction.java
         |-- resources
         |   `-- images
         |       `-- sampleimage.jpg
         `-- webapp
             |-- WEB-INF
             |   `-- web.xml
             |-- index.jsp
             `-- jsp
                 `-- websource.jsp

The WAR file it generates has the structure as below which is again based on defaults -

  |-- META-INF
  |   |-- MANIFEST.MF
  |   `-- maven
  |       `-- com.example.projects
  |           `-- documentedproject
  |               |-- pom.properties
  |               `-- pom.xml
  |-- WEB-INF
  |   |-- classes
  |   |   |-- com
  |   |   |   `-- example
  |   |   |       `-- projects
  |   |   |           `-- SampleAction.class
  |   |   `-- images
  |   |       `-- sampleimage.jpg
  |   `-- web.xml
  |-- index.jsp
  `-- jsp
      `-- websource.jsp

I want to rename web-prod.xml to web.xml , which reside under webapp directory, before packaging into WAR. Now the catch is - contents of this directory are copied into target/<finalName> by the maven-war-plugin only during the packaging phase and immediately the WAR is generated.
Since webapp contents are copied by default by maven-war-plugin , other plugins like maven-compiler-plugin and maven-resources-plugin which come into picture early, don't have any role in modifying the said file.

pom.xml

<build>
    ...
    <plugins>
        ...
        <plugin>
            <artifactId>maven-antrun-plugin</artifactId>
            <executions>
                <execution>
                    <id>replace-descriptor</id>
                    <phase>compile</phase>
                    <goals>
                        <goal>run</goal>
                    </goals>
                    <configuration>
                        <target>
                            <delete file="${project.build.directory}/${project.finalName}/WEB-INF/web.xml" />
                            <move file="${project.build.directory}/${project.finalName}/WEB-INF/web-prod.xml" tofile="${project.build.directory}/${project.finalName}/WEB-INF/web.xml"/>
                        </target>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <artifactId>maven-war-plugin</artifactId>
            <configuration>
                <archiveClasses>true</archiveClasses>
                <attachClasses>true</attachClasses>
                <warSourceIncludes>WEB-INF/**</warSourceIncludes>
                <packagingExcludes>WEB-INF/classes</packagingExcludes>
                <webResources>
                    <resource>
                        <directory>src/main/resources</directory>
                        <targetPath>WEB-INF/classes</targetPath>
                        <includes>
                            ...
                        </includes>
                    </resource>
                    <resource>
                        <directory>${project.build.directory}/classes</directory>
                        <includes>
                            ...
                        </includes>
                        <targetPath>WEB-INF/classes</targetPath>
                    </resource>
                </webResources>
            </configuration>
        </plugin>
    </plugins>
</build>

web.xml

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" metadata-complete="true" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
    <display-name>NSWeb</display-name>
    ...
    <filter>
        <filter-name>corsFilter</filter-name>
        <filter-class>com.example.core.security.filter.CORSFilter</filter-class>
    </filter>
    ...
</web-app>

web-prod.xml

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" metadata-complete="true" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
    <display-name>NSWeb</display-name>
    ...
    <filter>
        <filter-name>corsFilter</filter-name>
        <filter-class>com.example.core.security.filter.CORSFilter</filter-class>
        <init-param>
            <description>A comma separated list of allowed origins. Note: An '*' cannot be used for an allowed origin when using credentials.</description>
            <param-name>cors.enabled</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            ...
        </init-param>
        <init-param>
            ...
        </init-param>
        <init-param>
            ...
        </init-param>
        ...
    </filter>
    ...
</web-app>

Thanks eis for pointing me to the filtering feature !
Earlier I maintained two different web.xml files and was trying to replace one with the other since there was a difference of around 40 lines of block between those two files. I could achieve the end result by modifying the same and NOT by replacing it with the other. Here's the solution explained stepwise:

  1. Have a single web.xml file with a placeholder to be replaced with the block.
  2. Enable resource filtering for maven-war-plugin and use the profiles.
  3. Have two different properties files to store the target specific values for the placeholder.

web.xml

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" metadata-complete="true" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
    <display-name>NSWeb</display-name>
    ...
    <filter>
        <filter-name>corsFilter</filter-name>
        <filter-class>com.example.core.security.filter.CORSFilter</filter-class>
        @web.xml.cors.config@
    </filter>
    ...
</web-app>

pom.xml

<build>
    ...
    <filters>
        <filter>src/main/resources/place-holders-${targetenv}.properties</filter>
    </filters>
    <plugins>
        
        <plugin>
            <artifactId>maven-war-plugin</artifactId>
            <configuration>
                ...
                <webResources>
                    ...
                    <resource>
                        <directory>${basedir}/src/main/webapp/WEB-INF</directory>
                        <filtering>true</filtering>
                        <targetPath>WEB-INF</targetPath>
                        <includes>
                            <include>**/web.xml</include>
                        </includes>
                    </resource>
                </webResources>
            </configuration>
        </plugin>
    </plugins>
</build>
<profiles>
    <profile>
        <id>dev</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <targetenv>dev</targetenv>
        </properties>
    </profile>
    <profile>
        <id>prod</id>
        <properties>
            <targetenv>prod</targetenv>
        </properties>
    </profile>
</profiles>

place-holders-dev.properties [just a blank/empty space for dev]

web.xml.cors.config= 

place-holders-prod.properties

web.xml.cors.config=<init-param>\
\n\t\t\t<description>A comma separated list of allowed origins. Note An '*' cannot be used for an allowed origin when using credentials.</description>\
\n\t\t\t<param-name>cors.enabled</param-name>\
\n\t\t\t<param-value>true</param-value>\
\n\t\t</init-param>\
\n\t\t<init-param>\
        ...
\n\t\t</init-param>\
\n\t\t<init-param>\
        ...
\n\t\t</init-param>\
        ...
        ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM