【问题标题】:How to include filtered resources into WEB-INF/classes using maven-resources-plugin?如何使用 maven-resources-plugin 将过滤后的资源包含到 WEB-INF/类中?
【发布时间】:2018-01-07 20:39:02
【问题描述】:

我正在使用 maven-resources-plugin,因为我在进行过滤时需要使用自定义分隔符。我的神器是 WAR。

我的src/main/resources 目录中有一些资源。通常,在打包 WAR 时,此目录中的任何内容都会以 WEB-INF/classes 结尾。但我需要先过滤这些资源,然后放入WEB-INF/classes 目录。我很难配置 maven-resources-plugin 来做到这一点。有什么办法吗?

我的 POM 如下所示:

<build>
    <finalName>my-app</finalName>
    <filters>
        <filter>${basedir}/src/main/properties/base.properties</filter>
    </filters>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <version>3.0.2</version>
            <executions>
                <execution>
                    <id>copy-resources</id>
                    <phase>validate</phase>
                    <goals>
                        <goal>copy-resources</goal>
                    </goals>
                    <configuration>
                        <overwrite>true</overwrite>
                        <useDefaultDelimiter>false</useDefaultDelimiter>
                        <delimiters>
                            <delimiter>@</delimiter>
                        </delimiters>
                        <outputDirectory>${project.build.directory}</outputDirectory>
                        <resources>
                            <resource>
                                <directory>
                                    ${basedir}/src/main/resources
                                </directory>
                                <filtering>true</filtering>
                            </resource>
                        </resources>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

【问题讨论】:

    标签: java maven pom.xml maven-resources-plugin


    【解决方案1】:

    简答:

    阶段错误,validate 是第二阶段,应该只用于验证构建环境并且在默认的process-resources 阶段之前,所以你的正确文件会被覆盖。

    长答案:

    基本上,您有两个选项可以解决您的问题:

    使用不同的/新的执行复制

    如果你真的需要不同的行为。

    在这种情况下,您的阶段是错误的。会发生什么:

    • 在验证阶段(为什么会有?),资源被正确过滤和复制
    • process-resources 阶段,资源插件的default-resources 执行运行目标copy-resources,它会在未过滤状态下再次覆盖您过滤的资源。

    如果您真的想这样做,请将资源放入与src/main/resources 不同的目录中,将执行阶段更改为适当的(以免混淆)并更改执行的 id (类似于copy-specially-filtered-resource - id 可以用来解释为什么需要第二次执行)

    另外,输出目录错误(需要是:${project.build.outputDirectory}directory 仅指向目标文件夹。

     <build>
        <finalName>my-app</finalName>
        <filters>
            <filter>${basedir}/src/main/properties/base.properties</filter>
        </filters>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>3.0.2</version>
                <executions>
                    <execution>
                        <id>copy-special-resources</id>
                        <phase>process-resources</phase>
                        <goals>
                            <goal>copy-resources</goal>
                        </goals>
                        <configuration>
                            <overwrite>true</overwrite>
                            <useDefaultDelimiter>false</useDefaultDelimiter>
                            <delimiters>
                                <delimiter>@</delimiter>
                            </delimiters>
                            <outputDirectory>${project.build.outputDirectory}</outputDirectory>
                            <resources>
                                <resource>
                                    <directory>
                                        ${basedir}/src/main/filtered
                                    </directory>
                                    <filtering>true</filtering>
                                </resource>
                            </resources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    

    此外,在这种情况下,我也会将过滤器放入执行配置中(其他所有内容都具有误导性)。

    首选:只需重新配置资源插件

    更简单、更简单的方法是简单地重新配置资源插件,激活全局资源过滤并使用默认执行(但是,这对于测试资源也是有效的):

    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
        <finalName>my-app</finalName>
        <filters>
            <filter>${basedir}/src/main/properties/base.properties</filter>
        </filters>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>3.0.2</version>
                <configuration>
                    <useDefaultDelimiter>false</useDefaultDelimiter>
                    <delimiters>
                        <delimiter>@</delimiter>
                    </delimiters>
                </configuration>
            </plugin>
        </plugins>
    </build>
    

    提示:使用override 配置通常是一种味道...

    【讨论】:

    • 您写过一个不存在的default-resources 目标。是默认生命周期绑定的maven-resources-plugin的执行Id。而且我不建议使用 maven-resources-plugin 因为可以配置 maven-war-plugin 来处理...
    • @khmarbaise 你是对的,我打错了。我的意思当然是目标copy-resources 的执行default-resources(代码本身是正确的)-我更正了。
    • @khmarbaise 至于resourceswar 插件,应该区分。如果我们使用类路径资源,我确实会使用资源插件,它通常用于类路径资源(因为战争插件也使用它)。但是,对于非类路径资源,我当然会使用 war 插件。但是,问题清楚地谈到了类路径资源(WEB-INF/classes)
    【解决方案2】:

    首先为什么不阅读maven-war-plugin的文档

    根据文档,您可以定义configuration to use a supplemental directory and activate filtering for that directory like this

     <configuration>
              <filters>
                <filter>properties/config.prop</filter>
              </filters>
              <nonFilteredFileExtensions>
                <!-- default value contains jpg,jpeg,gif,bmp,png -->
                <nonFilteredFileExtension>pdf</nonFilteredFileExtension>
              </nonFilteredFileExtensions>
              <webResources>
                <resource>
                  <directory>resource2</directory>
                  <!-- it's not a good idea to filter binary files -->
                  <filtering>false</filtering>
                </resource>
                <resource>
                  <directory>configurations</directory>
                  <!-- enable filtering -->
                  <filtering>true</filtering>
                  <excludes>
                    <exclude>**/properties</exclude>
                  </excludes>
                </resource>
              </webResources>
            </configuration>
    

    我建议创建一个补充目录,例如 src/main/filtered-resources,您可以将其配置为进行过滤,而我不会更改默认资源目录(默认情况下不进行过滤)。这样更容易理解。

    如果您想更改分隔符,可以将配置添加到 maven-war-plugin,如下所示:

    <delimiters>
      <delimiter>@</delimiter>
    </delimiters>
    

    所以最终不需要对maven-resources-plugin等进行补充配置。

    【讨论】:

    • 当 OP 询问类路径资源时,恕我直言,应该使用过滤类路径资源的机制,即resources 插件。在您的示例中,过滤后的文件最终会出现在 War 文件的根目录中,而 OP 则希望它们出现在 WEB-INF 类中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-11
    • 2015-03-20
    • 2018-02-18
    • 2012-06-09
    • 2010-12-19
    • 1970-01-01
    • 2013-11-20
    相关资源
    最近更新 更多