如何修改内容或替换位于 Maven webapp 项目的 webapp 目录中的文件

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

我有一个 Maven webapp 项目。它的默认目录结构如下 -

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

它生成的WAR文件具有如下结构,再次基于默认值-

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

我想将 web-prod.xml 重命名为 web.xml,它位于 webapp目录,打包前进入WAR。 现在要注意的是 - 此目录的内容仅在打包阶段由 maven-war-plugin 复制到 target/<finalName>,并立即生成 WAR。
由于 webapp 内容默认由 maven-war-plugin 复制,其他插件如 maven-compiler-pluginmaven-resources-plugin 较早出现,没有任何作用在修改上述文件中。

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>

谢谢eis for pointing me to the filtering feature
早些时候,我维护了两个不同的 web.xml 文件,并试图用一个替换另一个,因为这两个文件之间有大约 40 行块的差异。 我可以通过修改相同的和 NOT 将其替换为另一个来实现最终结果。这是逐步解释的解决方案:

  1. 有一个 web.xml 文件,其中包含要替换为块的占位符。
  2. maven-war-plugin 启用资源过滤并使用配置文件。
  3. 有两个不同的属性文件来存储占位符的目标特定值。

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 [只是一个 blank/empty space for dev]

web.xml.cors.config= 

占位符-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>\
        ...
        ...