java Maven 字符串替换文本 Web 资源

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3018405/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 23:58:23  来源:igfitidea点击:

Maven String Replace of Text Web Resources

javamaven-2packagewarphase

提问by Jaco van Niekerk

I have a Maven web application with text files in

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

src/main/webapp/textfilesdir

src/main/webapp/textfilesdir

As I understand it, during the package phase this textfilesdir directory will be copied into the

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

target/project-1.0-SNAPSHOT

目标/项目-1.0-快照

directory, which is then zipped up into a

目录,然后将其压缩为

target/project-1.0-SNAPSHOT.war

目标/项目-1.0-SNAPSHOT.war

Problem

问题

Now, I need to do a string replacement on the contents of the text files in target/project-1.0-SNAPSHOT/textfilesdir. This must then be done after the textfilesdir is copied into target/project-1.0-SNAPSHOT, but prior to the target/project-1.0-SNAPSHOT.war file being created. I believe this is all done during the package phase.

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

How can a plugin (potentially maven-antrun-plugin), plug into the package phase to do this.

插件(可能是 maven-antrun-plugin)如何插入到包阶段来做到这一点。

The text files don't contain properties, like ${property-name} to filter on. String replacement is likely the only option.

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

Options

选项

  1. Modify the text files after the copy into target/project-1.0-SNAPSHOT directory, yet prior to the WAR creation.

  2. After packaging, extract the text files from WAR, modify them, and add them back into the WAR.

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

  2. 打包后,从 WAR 中提取文本文件,修改它们,然后将它们添加回 WAR。

I'm thinking there is another option here I'm missing. Thoughts anyone?

我想这里还有另一种选择,我错过了。有人想吗?

采纳答案by Pascal Thivent

Option 1 is not doable, prepare-packageis too early, packageis too late so I don't see where you could plug any custom work. Option 2 is doable but a painful IMO. So here are some more propositions (all based on AntRun and the ReplaceRegExpand/or Replacetasks).

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

Solution 1:

解决方案1:

  1. Create a new folder where you put the text files that need to be processed.
  2. Bind the antrun plugin to prepare-packageand configure it to process the files and put the processed files in some directory under target(e.g. target/textfilesdir).
  3. Configure the war plugin to include target/textfilesdiras a webResource. Refer to Adding and Filtering External Web Resourcesfor the details.
  1. 创建一个新文件夹,用于放置需要处理的文本文件。
  2. 绑定antrun插件prepare-package并配置它处理文件并将处理后的文件放在target(例如target/textfilesdir)下的某个目录中。
  3. 配置 war 插件以包含target/textfilesdirwebResource. 有关详细信息,请参阅添加和过滤外部 Web 资源

Solution 2:

解决方案2:

  1. Bind the antrun plugin to prepare-packageand configure it to process the text files from src/main/webapp/textfilesdirand put the processed files in the target/project-1.0-SNAPSHOT.
  2. Configure the war plugin to exclude the previously processed files. Again, refer to Adding and Filtering External Web Resourcesfor the details.
  1. 绑定antrun插件prepare-package并将其配置为处理来自文本文件src/main/webapp/textfilesdir,并把处理的文件中target/project-1.0-SNAPSHOT
  2. 配置war插件以排除之前处理​​过的文件。同样,请参阅添加和过滤外部 Web 资源以获取详细信息。

I think I'd go for the second solution.

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

回答by fixje

I had the same problem and I was fiddling a lot with this issue, so I will answer although this question is pretty old. As stated by leandro and Phil, one can use the maven-replacer-plugin. But their solution didn't work for me. Enabling useCachecaused an error which made it impossible to build the project. Additionally, I can't make the auto-clean thing to work properly. As I am not allowed yet to comment on the post, I will provide my full solution here:

我遇到了同样的问题,我在这个问题上摆弄了很多,所以我会回答,尽管这个问题已经很老了。正如leandro 和Phil 所说,可以使用maven-replacer-plugin。但是他们的解决方案对我不起作用。启用会useCache导致无法构建项目的错误。此外,我无法使自动清洁功能正常工作。由于我还不能对帖子发表评论,我将在这里提供我的完整解决方案:

First of all, configure the maven-replacer-plugin:

首先,配置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>

Before the actual war is built, we create an exploded war. This means, the whole content of the war file is stored in a sub directory (which is target/${project.build.finalName} by default). After that, the maven-replacer-plugin will change the contents of the files as we have specified. Finally, the .war will be packed in the package phase by the default-warjob. To avoid the content of the exploded war folder being overridden, one has to set warSourceDirectoryto the directory where the exploded war stuff is stored. The following configuration snippet will do this job:

在真正的War建立之前,我们制造了一场爆炸式的War。这意味着,war 文件的全部内容都存储在一个子目录中(默认为 target/${project.build.finalName})。之后,maven-replacer-plugin 将更改我们指定的文件内容。最后,.war 将被作业打包到打包阶段default-war。为避免已分解的war文件夹的内容被覆盖,必须设置warSourceDirectory为存储已分解的war内容的目录。以下配置片段将完成这项工作:

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

The package with the replaced content can be built using mvn clean package

可以使用替换内容构建包 mvn clean package

回答by Marcelo Maico

I had a problem with the phases, using prepare-package not copied the file to war, my solution was this:

我的阶段有问题,使用prepare-package没有将文件复制到war,我的解决方案是这样的:

Add this configuration in maven-war-plugin

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

The output File not overwrite the file, so i put the configuration maven-war-plugin to exclude the file style.scss. bye!

输出文件不会覆盖文件,所以我把配置 maven-war-plugin 排除在文件 style.scss 之外。再见!

回答by Ducaz035

Another solution from me, sorry for being late to the party but still might be useful for some people. Solution above simply didn't work for me because I had overlays in place and therefore using the replacer plugin was hard in the main source. Hence, I used maven-war-plugin to generate the temporary directory for me in the prepare-package phase and have replacer plugin to manipulate it and release the war from that directory so that nothing else overrides with it.

我的另一个解决方案,很抱歉迟到了,但仍然可能对某些人有用。上面的解决方案根本不适合我,因为我有覆盖层,因此在主源中使用替换插件很困难。因此,我使用 maven-war-plugin 在准备包阶段为我生成临时目录,并使用替换插件来操作它并从该目录中释放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>

回答by Leandro

You can use maven-replacer-plugin:

您可以使用 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>

But you need two more tricks. One is adding the explode goal to the war plugin:

但是你还需要两个技巧。一种是将爆炸目标添加到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>

And finally to need to call mvn clean before the package. You can do it from your pom:

最后需要在打包之前调用 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>

If you are using a version of the maven-war-plugin newer than 2.0.1, you will need to include true in the configuration of the maven-war-plugin, otherwise the changes to your file(s) will be splotted when the war plugin copies your webapp over a second time. If you are using Hudson/Jenkins, you will have to use a version newer than 2.0.1.

如果您使用的 maven-war-plugin 版本高于 2.0.1,则需要在 maven-war-plugin 的配置中包含 true,否则对文件的更改将在War插件第二次复制您的网络应用程序。如果您使用 Hudson/Jenkins,则必须使用比 2.0.1 更新的版本。