18

我有一个带有文本文件的 Maven Web 应用程序

src/main/webapp/textfilesdir

据我了解,在打包阶段这个 textfilesdir 目录将被复制到

目标/project-1.0-SNAPSHOT

目录,然后将其压缩到一个

目标/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 中。

我想这里还有另一种选择。有人想吗?

4

5 回答 5

8

我遇到了同样的问题,我在这个问题上摆弄了很多,所以我会回答虽然这个问题已经很老了。正如leadro 和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>

在实际战争建立之前,我们制造了一场爆炸战争。这意味着,war 文件的全部内容存储在一个子目录中(默认为 target/${project.build.finalName})。之后,maven-replacer-plugin 将按照我们指定的方式更改文件的内容。最后,.war 将被default-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

于 2012-09-28T13:30:40.450 回答
5

选项 1 不可行,prepare-package太早,package太晚,所以我看不出你可以在哪里插入任何自定义工作。选项 2 是可行的,但 IMO 很痛苦。所以这里有更多的命题(都基于 AntRun 和ReplaceRegExp和/或Replace任务)。

解决方案1:

  1. 创建一个新文件夹,放置需要处理的文本文件。
  2. 绑定antrun插件prepare-package并配置它来处理文件并将处理后的文件放在target(例如target/textfilesdir)下的某个目录中。
  3. 将战争插件配置为包含target/textfilesdirwebResource. 有关详细信息,请参阅添加和过滤外部 Web 资源

解决方案2:

  1. 将 antrun 插件绑定到prepare-package并配置它以处理来自的文本文件,src/main/webapp/textfilesdir并将处理后的文件放在target/project-1.0-SNAPSHOT.
  2. 配置war插件以排除之前处理​​过的文件。同样,有关详细信息,请参阅添加和过滤外部 Web 资源

我想我会选择第二种解决方案。

于 2010-06-10T21:05:31.480 回答
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 之外。再见!

于 2012-11-08T12:30:20.943 回答
2

我的另一个解决方案,很抱歉迟到了,但对某些人来说仍然可能有用。上面的解决方案根本不适合我,因为我有覆盖,因此在主要来源中使用替换插件很困难。因此,我在准备包阶段使用 maven-war-plugin 为我生成临时目录,并使用替换插件来操作它并从该目录中释放战争,以便没有其他任何东西被它覆盖。

      <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>
于 2016-10-13T11:16:03.240 回答
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>

但是你还需要两个技巧。一种是在战争插件中添加爆炸目标:

<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,否则在战争插件第二次复制您的网络应用程序。如果您使用的是 Hudson/Jenkins,则必须使用高于 2.0.1 的版本。

于 2011-04-04T16:02:34.490 回答