Maven字符串替换Web资源文本

19

我有一个基于Maven的Web应用程序,其中文本文件位于

src/main/webapp/textfilesdir

据我所知,在打包阶段期间,此textfilesdir目录将被复制到

target/project-1.0-SNAPSHOT

目录,然后被压缩成

target/project-1.0-SNAPSHOT.war

问题

现在,我需要在target/project-1.0-SNAPSHOT/textfilesdir中对文本文件的内容进行字符串替换。这必须在textfilesdir复制到target/project-1.0-SNAPSHOT之后但在创建target/project-1.0-SNAPSHOT.war文件之前完成。我相信这都是在打包阶段完成的。

如何使用插件(可能是maven-antrun-plugin)来连接打包阶段以执行此操作。

文本文件不包含属性,例如${property-name},以进行过滤。字符串替换可能是唯一的选项。

选项

  1. 在将文件复制到target/project-1.0-SNAPSHOT目录之后,但在WAR创建之前修改文本文件。

  2. 打包后,从WAR中提取文本文件,对其进行修改,然后将其重新添加到WAR中。

我认为还有另一种选择,但我可能错过了。大家有什么想法吗?

5个回答

9

我曾经遇到过同样的问题,并且为此问题进行了很多尝试,所以尽管这个问题已经很旧了,但我还是想回答一下。正如leandro和Phil所说,可以使用maven-replacer-plugin来解决问题。但他们的解决方案对我并不起作用。启用useCache会导致一个错误,使得项目无法构建。此外,我无法使自动清理工具正常工作。

首先,配置maven-replacer-plugin:

<plugin> 
  <groupId>com.google.code.maven-replacer-plugin</groupId>
  <artifactId>maven-replacer-plugin</artifactId>
  <version>1.3.7</version>
  <executions>
    <execution>
      <phase>prepare-package</phase>
      <goals>
        <goal>replace</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <includes>
      <include>target/${project.build.finalName}/static/**/*.css</include>
    </includes>
    <regex>false</regex>
    <token>someString</token>
    <value>replaceString</value>
  </configuration>
</plugin>

在实际构建战争之前,我们创建了一个爆炸的战争。这意味着,整个战争文件的内容存储在一个子目录中(默认情况下为target/${project.build.finalName})。之后,maven-replacer-plugin将根据我们指定的内容更改文件的内容。最后,在“default-war”作业的打包阶段,.war将被打包。为避免覆盖爆炸式战争文件夹的内容,必须将 warSourceDirectory 设置为存储爆炸式战争材料的目录。以下配置片段将完成此工作:
<plugin>
  <artifactId>maven-war-plugin</artifactId>
  <version>2.1.1</version>
  <executions>
    <execution>
      <id>prepare</id>
      <phase>prepare-package</phase>
      <goals>
        <goal>exploded</goal>
  </goals>
    </execution>
    <execution> 
      <id>default-war</id>
      <phase>package</phase>
      <goals>
        <goal>war</goal>
      </goals>
      <configuration>
        <warSourceDirectory>${project.build.directory}/${project.build.finalName}</warSourceDirectory>
      </configuration>
    </execution>
  </executions>
</plugin>

可以使用mvn clean package构建替换内容的软件包。

5
选项1不可行,因为prepare-package太早了,而package太晚了,所以我不知道你在哪里可以插入任何自定义工作。选项2是可行的,但在我看来很痛苦。因此,这里有一些更多的建议(都基于AntRun和ReplaceRegExp和/或Replace任务)。
解决方案1:
  1. 创建一个新文件夹,将需要处理的文本文件放入其中。
  2. 将antrun插件绑定到prepare-package,并配置它以处理文件并将处理后的文件放置在target下的某个目录中(例如target/textfilesdir)。
  3. 配置war插件将target/textfilesdir作为webResource包含进去。有关详细信息,请参阅添加和过滤外部Web资源
解决方案2:
  1. 将antrun插件绑定到prepare-package,并配置它以处理src/main/webapp/textfilesdir中的文本文件,并将处理后的文件放置在target/project-1.0-SNAPSHOT中。
  2. 配置war插件以排除先前处理过的文件。同样,请参阅添加和过滤外部Web资源以获取详细信息。
我认为我会选择第二个解决方案。

通常情况下,我建议使用gmaven(http://docs.codehaus.org/display/GMAVEN/Executing+Groovy+Code)来嵌入Groovy而不是Ant,但除此之外,我完全同意(+1)。 - Sean Patrick Floyd
@seanizer:我需要更多地思考Groovy :) 它肯定会在这里发挥出色。 - Pascal Thivent
没错。虽然我不太热衷于构建 Groovy 应用程序(如 Grails 等),但我认为 Groovy 绝对是一种被低估的脚本语言。 - Sean Patrick Floyd
同意,选项2听起来是正确的方式。我想知道是否可能有另一种方法,但这比我最初想象的pom配置要少。谢谢! Ant来帮忙了吗? :) - Jaco van Niekerk

3
我遇到了一个与阶段有关的问题,在使用prepare-package时,没有将文件复制到war中,我的解决方案是:

在maven-war-plugin中添加以下配置:

<plugin>
             <groupId>org.apache.maven.plugins</groupId> 
             <artifactId>maven-war-plugin</artifactId> 
              <version>2.1.1</version> 
         <executions>
          <execution>
               <phase>prepare-package</phase>
               <goals>
                    <goal>exploded</goal>
               </goals>
          </execution>
          <executions> 
               <configuration>
               <webResources>
                    <resource>
                         <directory>${basedir}/WebContent?</directory> <excludes>
               <!--Exclude the file because it is copied using the maven replacer plugin -->
                         <exclude>/style.scss</exclude>
                         </excludes>
                    </resource>
               </webResources>
          </configuration>
          </plugin>
          Add the configuration to replacer 
 <plugin>
       <groupId>com.google.code.maven-replacer-plugin</groupId> 
       <artifactId>replacer</artifactId> 
       <version>1.5.1</version> 
       <executions>
          <execution>
               <id>scss-replacement</id> <phase>prepare-package</phase> <goals>
               <goal>replace</goal>
               </goals> <configuration>
               <file>WebContent?/css/style.scss</file>
               <!-- My local file(WebContent?/css/style.scss) have a param
               $url: "http://localhost:8080/interface";
               --> <!-- regex with match to $url: "http://localhost:8080/interface"; -->
               <token>\$url:.</token>
               <!-- Replace to -->
               <value>\$url: "www.myapplication.com.br/css/style.css";</value>
               <outputFile>target/app/css/style.scss</outputFile>

               </configuration>
          </execution>
     <executions>
<plugin>

输出文件不会覆盖原始文件,因此我将配置maven-war-plugin以排除文件style.scss。拜拜!


2

我提供另一种解决方案,很抱歉来晚了,但对某些人可能仍然有用。上面的解决方案对我来说根本不起作用,因为我已经放置了覆盖层,因此在主源中使用替换插件很困难。因此,我使用maven-war-plugin在prepare-package阶段为我生成临时目录,并使用replacer插件对其进行操作并从该目录释放war文件,以便没有其他内容会覆盖它。

      <plugin>
    <artifactId>maven-war-plugin</artifactId>
    <executions>
      <execution>
        <id>prepare</id>
        <phase>prepare-package</phase>
        <goals>
          <goal>exploded</goal>
        </goals>
        <configuration>
          <webappDirectory>${project.build.directory}/${project.build.finalName}-patched/</webappDirectory>
        </configuration>
      </execution>
      <execution>
        <id>default-war</id>
        <phase>package</phase>
        <goals>
          <goal>war</goal>
        </goals>
        <configuration>
          <useCache>true</useCache>
          <warSourceDirectory>${project.build.directory}/${project.build.finalName}-patched/</warSourceDirectory>
        </configuration>
      </execution>
    </executions>
  </plugin>
  <plugin>
    <groupId>com.google.code.maven-replacer-plugin</groupId>
    <artifactId>replacer</artifactId>
    <executions>
      <execution>
        <phase>prepare-package</phase>
        <goals>
          <goal>replace</goal>
        </goals>
      </execution>
    </executions>
    <configuration>
      <file>${project.build.directory}/${project.build.finalName}-patched/fileToBeChanged.txt</file>
      <token>ValueToChange</token>
      <value>ValueToReplace</value>
    </configuration>
  </plugin>

1
你可以使用maven-replacer-plugin插件:
<plugin>
       <groupId>com.google.code.maven-replacer-plugin</groupId>
       <artifactId>maven-replacer-plugin</artifactId>
       <version>1.3.7</version>
       <executions>
           <execution>
               <phase>prepare-package</phase>
               <goals>
                   <goal>replace</goal>
               </goals>                   
           </execution>
       </executions>
       <configuration>
           <file>target/${project.artifactId}-${project.version}/WEB-IN/site.xml</file>
           <replacements>
               <replacement>
                   <token>ear.version</token>
                   <value>${ear.version}-${maven.build.timestamp}</value>
               </replacement>         
           </replacements>
       </configuration>
   </plugin>

但你需要两个更多的技巧。一个是将explode目标添加到war插件中:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.1.1</version>
        .....
        <executions>
        <execution>
        <phase>prepare-package</phase>
            <goals>
                 <goal>exploded</goal>
             </goals>
         </execution>
    </executions>
</plugin>

最后,在打包之前需要调用mvn clean。您可以在pom文件中执行此操作:
                   <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>2.4.1</version>
                    <executions>
                      <execution>
                        <id>auto-clean</id>
                        <phase>initialize</phase>
                        <goals>
                          <goal>clean</goal>
                        </goals>
                      </execution>
                    </executions>
            </plugin>

如果您使用的是maven-war-plugin 2.0.1以上的版本,则需要在maven-war-plugin的配置中包含true,否则当war插件第二次复制您的Web应用程序时,对文件所做的更改将被覆盖。如果您正在使用Hudson/Jenkins,则必须使用2.0.1以上的版本。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接