Maven War 插件詳解

WAR 插件負責收集 Web 應用程序的所有依賴項、類和資源,并將它們打包到 WAR 包中,僅包含 scopecompile+runtime 的依賴項,默認綁定到 package 階段。詳情請參考:https://maven.apache.org/plugins/maven-war-plugin/

使用 War 插件有 4 種方法:

  • package 階段使用 war 打包類型;
  • 調用 war:war 目標;
  • 調用 war:exploded 目標;
  • 調用 war:inplace 目標;

當使用 war: 目標時,WAR 插件假定 compile 階段已經完成。WAR 插件不負責編譯 Java 源代碼或復制資源文件。

為了處理歸檔,這個版本的 Maven WAR 插件使用 Maven Archiver 3.5.0 來進行歸檔,使用 Maven Filtering 3.1.1 來處理資源文件中的屬性引用替換。

調用 war:war 目標

這是使用 WAR 插件的一般方式。需要解析 scopecompile+runtime 的依賴項,默認綁定到 package 階段。

下面是一個示例項目的 pom.xml:

<project>
  ...
  <groupId>com.example.projects</groupId>
  <artifactId>documentedproject</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>Documented Project</name>
  <url>http://example.com</url>
  ...
</project>

項目的結構如下所示:

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

調用:mvn packagemvn compile war:war,將生成 war 文件 target/documentedproject-1.0-SNAPSHOT.WAR。以下是該 WAR 文件的內容:

documentedproject-1.0-SNAPSHOT.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

war:war 目標的全部參數介紹

必需的參數

  • <outputDirectory>:生成的 WAR 文件的目錄。默認為 ${project.build.directory}
  • <warSourceDirectory>:用于在 WAR 中包含額外文件的單個目錄。這是您放置 JSP 文件的地方。默認為 ${basedir}/src/main/webapp
  • <webappDirectory>:指定解壓形式的 WAR 的默認輸出目錄,默認為 ${project.build.directory}/${project.build.finalName} 可以是外部 Web 容器的部署目錄以便直接運行,比如 Tomcat 的 webapps 目錄。
  • <workDirectory>:將所依賴的 WAR 包解壓縮的輸出目錄(如果需要的話)。默認為 ${project.build.directory}/war/work

可選的參數

  • <archive>:要使用的存檔配置。參見 Maven Archiver 參考資料

  • <archiveClasses>:是否將 webapp 中的 .class 文件打包成 JAR 文件。使用此可選配置參數將使編譯后的類歸檔到 /WEB-INF/lib/ 中的 JAR 文件中,然后將 classes 目錄從 webapp/WEB-INF/classes/ 中排除。默認值為:false

  • <containerConfigXML>:servlet 容器的配置文件的路徑。請注意,對于不同的 servlet 容器,文件名可能不同。Apache Tomcat 使用名為 context.xml 的配置文件。該文件將被復制到 META-INF 目錄。

  • <delimiters>:在資源中用于屬性引用替換的表達式的一組分隔符。這些分隔符以 beginToken*endToken 的形式指定。如果未給出 *,則假定起始和結束的分隔符相同。因此,可以將默認分隔符指定為:

    <delimiters>
      <delimiter>${*}</delimiter>
      <delimiter>@</delimiter>
    </delimiters>
    

    由于兩端的 @ 分隔符相同,因此不需要指定 @*@(盡管也可以這樣指定)。

  • <dependentWarExcludes>:進行 WAR 覆蓋時要進行排除的逗號分隔的標記列表。默認值為 Overlay.DEFAULT_EXCLUDES

  • <dependentWarIncludes>:進行 WAR 覆蓋時要進行包含的逗號分隔的標記列表。默認值為 Overlay.DEFAULT_INCLUDES

  • <escapeString>:前面帶有此字符串的表達式將不會被插值替換,比如 \${foo} 將替換為 ${foo}

  • <escapedBackslashesInFilePath>:是否轉義 Windows 路徑,默認為 false。比如,c:\foo\bar 將替換為 c:\\foo\\bar

  • <failOnMissingWebXml>:如果 web.xml 文件丟失,是否使構建失敗。如果希望在不使用 web.xml 文件的情況下生成 WAR 包,請將其設置為 false。如果要構建沒有 web.xml 文件的 WAR 包,這可能很有用。從 3.1.0 開始,如果項目依賴于 Servlet 3.0 API 或更新版本,則此屬性默認為 false

  • <filteringDeploymentDescriptors>:是否過濾部署描述符(如 web.xml)中的插值。默認情況下 false

  • <filters>:在 pom.xml 的插值過程中要包含的過濾器(property 文件),可以通過若干個 <filter> 子元素指定一個 property 文件列表。

  • <includeEmptyDirectories>:是否包含空目錄。默認為 false

  • <nonFilteredFileExtensions>:不應篩選的文件擴展名列表。將在篩選 webResourcesoverlays 時使用。

  • <outdatedCheckPath>:將根據過期內容檢查的資源的路徑前綴。從 3.3.2 開始,如果指定了 / 值,則將檢查整個 webappDirectory,即 / 表示根目錄。默認為 WEB-INF/lib/

  • <outputFileNameMapping>:復制庫和 TLD 時要使用的文件名映射。如果未設置文件映射(默認),則將使用文件的標準名稱復制文件。。

  • <outputTimestamp>:可重復輸出存檔項的時間戳,格式為 ISO 8601 yyyy-MM-dd'T'HH:mm:ssXXX 或表示自紀元起的整秒數(如SOURCE_DATE_EPOCH)。默認為 ${project.build.outputTimestamp}

  • <overlays>:要應用的覆蓋層。每個 <overlay> 子元素可能包含:

    • id:默認為 currentBuild
    • groupId:如果該元素和 artifactId 為 null,則當前項目將被視為自己的覆蓋。
    • artifactId:見上文。
    • classifier
    • type
    • includes:字符串模式列表。
    • excludes:字符串模式列表。
    • filtered:默認為 false
    • skip:默認為 false
    • targetPath:默認為 webapp 結構的根目錄。
  • <recompressZippedFiles>:指示是否應再次壓縮添加到 WAR 中的 zip 存檔(jar、zip 等)。再次壓縮可能會導致較小的存檔大小,但會顯著延長執行時間。默認為 true

  • <resourceEncoding>:復制那些篩選的 Web 資源時要使用的編碼。默認為 ${project.build.sourceEncoding}

  • <supportMultiLineFiltering>:停止搜索行末尾的 endToken。默認為 false

  • <useDefaultDelimiters>:除了自定義分隔符(如果有)之外,還使用默認分隔符。默認為 true

  • <useJvmChmod>:使用 jvmChmod 而不是 cli chmod 和 forking 過程。默認為 true

  • <warSourceExcludes>:復制 warSourceDirectory 內容時要排除的標記的逗號分隔列表。

  • <warSourceIncludes>:復制 warSourceDirectory 內容時要包含的標記的逗號分隔列表。

  • <webResources>:要傳輸的 Web 資源列表,通過若干個 <resource> 子元素來指定這樣一個資源列表,每個資源使用相對于 pom.xml 文件的路徑。

  • <webXml>:要使用的 web.xml 文件的路徑。

調用 war:exploded 目標

為了在開發階段加快測試速度,war:exploded 可以用來生成解壓形式的 WAR。需要解析 scoperuntime 的依賴項,默認綁定到 package 階段。

使用上述項目并調用:mvn compile war:exploded。這將在target/documentedproject-1.0-SNAPSHOT 中生成 WAR 的解壓版本。該目錄的內容如下所示:

 documentedproject-1.0-SNAPSHOT
 |-- META-INF
 |-- WEB-INF
 |   |-- classes
 |   |   |-- com
 |   |   |   `-- example
 |   |   |       `-- projects
 |   |   |           `-- SampleAction.class
 |   |   `-- images
 |   |       `-- sampleimage.jpg
 |   `-- web.xml
 |-- index.jsp
 `-- jsp
     `-- websource.jsp

解壓形式的 WAR 的默認輸出目錄是 ${project.build.directory}/${project.build.finalName},即 target/<finalName>,最終名稱通常采用 <artifactId>-<version> 的形式。可以通過指定 webappDirectory 參數來覆蓋此默認目錄。

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>3.3.2</version>
        <configuration>
          <webappDirectory>/sample/servlet/container/deploy/directory</webappDirectory>
        </configuration>
      </plugin>
    </plugins>
  </build>
  ...
</project>

war:exploded 目標的全部參數

必需的參數

war:exploded 目標的必需參數比 war:war 目標的必選參數少了一個 <outputDirectory>

  • <warSourceDirectory>:用于在 WAR 中包含額外文件的單個目錄。這是您放置 JSP 文件的地方。默認為 ${basedir}/src/main/webapp
  • <webappDirectory>:指定解壓形式的 WAR 的默認輸出目錄,默認為 ${project.build.directory}/${project.build.finalName} 可以是外部 Web 容器的部署目錄以便直接運行,比如 Tomcat 的 webapps 目錄。
  • <workDirectory>:將所依賴的 WAR 包解壓縮的輸出目錄(如果需要的話)。默認為 ${project.build.directory}/war/work

可選的參數

war:exploded 目標的可選參數與 war:exploded 目標的可選參數相同。

調用 war:inplace 目標

war:exploded 的另一個變體是 war:inplace。使用war:inplace 創建的解壓形式的 WAR 的輸出目錄默認為 src/main/webapp。使用上述項目并調用:mvn compile war:inplace,結果如下:

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

war:inplace 目標的全部參數

需要解析 scoperuntime 的依賴項,默認綁定到 package 階段。

必需的參數

war:inplace 目標的必需參數比 war:war 目標的必選參數少了一個 <outputDirectory>

  • <warSourceDirectory>:用于在 WAR 中包含額外文件的單個目錄。這是您放置 JSP 文件的地方。默認為 ${basedir}/src/main/webapp
  • <webappDirectory>:指定解壓形式的 WAR 的默認輸出目錄,默認為 ${project.build.directory}/${project.build.finalName} 可以是外部 Web 容器的部署目錄以便直接運行,比如 Tomcat 的 webapps 目錄。
  • <workDirectory>:將所依賴的 WAR 包解壓縮的輸出目錄(如果需要的話)。默認為 ${project.build.directory}/war/work

可選的參數

war:inplace 目標的可選參數與 war:war 目標的可選參數相同。

Overlay

簡介

Overlay(覆蓋)用于跨多個 Web 應用程序共享公共資源。WAR 項目的依賴項收集在 WEB-INF/lib 中,WAR 項目本身上覆蓋的 WAR 工件除外。

以下面的項目結構來作為說明:

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

該項目依賴于另一個 WAR 工件 documentedprojectdependency-1.0-SNAPSHOT.war ,該工件在項目的 pom.xml 中聲明為依賴項:

<project>
  ...
  <dependencies>
    <dependency>
      <groupId>com.example.projects</groupId>
      <artifactId>documentedprojectdependency</artifactId>
      <version>1.0-SNAPSHOT</version>
      <type>war</type>
      <scope>runtime</scope>
    </dependency>
    ...
  </dependencies>
  ...
</project>

documentedprojectdependency 的 WAR 文件結構如下:

documentedprojectdependency-1.0-SNAPSHOT.war
 |-- META-INF
 |   |-- MANIFEST.MF
 |   `-- maven
 |       `-- com.example.projects
 |           `-- documentedprojectdependency
 |               |-- pom.properties
 |               `-- pom.xml
 |-- WEB-INF
 |   |-- classes
 |   |   |-- com
 |   |   |   `-- example
 |   |   |       `-- projects
 |   |   |           `-- SampleActionDependency.class
 |   |   `-- images
 |   |       `-- sampleimage-dependency.jpg
 |   `-- web.xml
 `-- index-dependency.jsp

最終合并的 WAR 文件如下:

 |-- META-INF
 |   |-- MANIFEST.MF
 |   `-- maven
 |       `-- com.example.projects
 |           `-- documentedproject
 |               |-- pom.properties
 |               `-- pom.xml
 |-- WEB-INF
 |   |-- classes
 |   |   |-- com
 |   |   |   `-- example
 |   |   |       `-- projects
 |   |   |           |-- SampleAction.class
 |   |   |           `-- SampleActionDependency.class
 |   |   `-- images
 |   |       |-- sampleimage-dependency.jpg
 |   |       `-- sampleimage.jpg
 |   `-- web.xml
 |-- index-dependency.jsp
 |-- index.jsp
 `-- jsp
     `-- websource.jsp

上面的 web.xml 文件來自 documentedproject 項目。

Overlay 類型

WAR 插件將 war 和 zip 工件作為覆蓋處理。但是,出于向后兼容性的原因,只有在插件的配置中明確定義 zip 覆蓋時,才會處理它們。

Overlay 配置

在以前版本的 WAR 插件中,不需要配置。如果您對默認設置感到滿意,這種情況仍然存在。<overlay> 元素可以有以下子元素:

  • id:Overlay 的 id。如果沒有提供,WAR 插件將生成一個。
  • groupId:要配置的 Overlay 工件的 groupId
  • artifactId:要配置的 Overlay 工件的 artifactId
  • classifier:如果多個工件與 groupId/artifactId 匹配,則要配置的 Overlay 工件的 classifier
  • type:要配置的 Overlay 工件的類型。默認值為 war。
  • includes:要包括的文件。默認情況下,包含所有文件。
  • excludes:要排除的文件。默認情況下,META-INF/MANIFEST.MF 文件被排除在外。
  • filtered:是否對此 Overlay 應用過濾。默認為 false
  • skip:設置為 true 可跳過此 Overlay。默認為 false
  • targetPathwebapp 結構中的目標相對路徑,僅適用于 war 類型的 Overlay。默認情況下,Overlay 的內容添加到 webapp 的根結構中。

例如,排除上面 documentedprojectdependency war 覆蓋的 sampleimage-dependency.jpg

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>3.3.2</version>
        <configuration>
          <overlays>
            <overlay>
              <groupId>com.example.projects</groupId>
              <artifactId>documentedprojectdependency</artifactId>
              <excludes>
                <exclude>WEB-INF/classes/images/sampleimage-dependency.jpg</exclude>
              </excludes>
            </overlay>
          </overlays>
        </configuration>
      </plugin>
    </plugins>
  </build>
  ...
</project>

Overlay 打包

Overlay 采用先贏策略(因此,如果一個文件已經被一個 Overlay 復制了,則另一個 Overlay 就不會復制該文件)。Overlay 按其在 <overlays> 配置中定義的順序應用。如果未提供任何配置,則使用 POM 中定義依賴項的順序(警告:這是不確定的,尤其是當 Overlay 是可傳遞依賴項時)。在混合情況下(例如,已配置的 Overlay 和沒有配置的 Overlay),在已配置的 Overlay 之后應用沒有配置的 Overlay。

默認情況下,首先添加項目源(當前構建的項目)(例如,在應用任何 Overlay 之前)。當前構建被定義為一個特殊的 Overlay,沒有 groupIdartifactId。如果需要首先應用 Overlay,只需在這些 Overlay 之后配置當前構建。

例如,如果 com.example.projects:my-webapp 是項目的依賴項,需要在該項目的源之前應用,請執行以下操作:

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>3.3.2</version>
        <configuration>
          <overlays>
            <overlay>
              <groupId>com.example.projects</groupId>
              <artifactId>my-webapp</artifactId>
            </overlay>
            <overlay>
              <!-- empty groupId/artifactId represents the current build -->
            </overlay>
          </overlays>
        </configuration>
      </plugin>
    </plugins>
  </build>
  ...
</project>

在上面的場景中,任何其他 WAR 依賴項都將在當前構建之后應用,因為它們尚未在 <overlays> 元素中配置。為了執行更細粒度的 Overlay 策略,可以使用不同的包含/排除多次打包 Overlay。例如,如果必須在 webapp 中設置 Overlay my-webapp 中的 index.jsp 文件,但其他文件可以通過常規方式控制,為 my-webapp 定義兩種 Overlay 配置:

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>3.3.2</version>
        <configuration>
          <overlays>
            <overlay>
              <id>my-webapp-index.jsp</id>
              <groupId>com.example.projects</groupId>
              <artifactId>my-webapp</artifactId>
              <includes>
                <include>index.jsp</include>
              </includes>
            </overlay>
            <overlay>
              <!-- empty groupId/artifactId represents the current build -->
            </overlay>
 
            <!-- Other overlays here if necessary -->
 
            <overlay>
              <id>my-webapp</id>
              <groupId>com.example.projects</groupId>
              <artifactId>my-webapp</artifactId>
            </overlay>
          </overlays>
        </configuration>
      </plugin>
    </plugins>
  </build>
  ...
</project>

Overlay 全局設置

可以全局指定以下設置,并修改應用所有 Overlay 的方式。

  • dependentWarIncludes 設置應用于所有 Overlay 的默認 includes 。默認情況下,沒有特定 includes 元素的任何 Overlay 都將繼承此設置。

    <project>
        ...
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>3.3.2</version>
            <configuration>
              <dependentWarIncludes>**/IncludeME,**/images</dependentWarIncludes>
            </configuration>
           </plugin>
        </plugins>
        ...
    </project>
    
  • dependentWarExcludes 設置要應用于所有 Overlay 的默認 excludes。默認情況下,沒有特定 excludes 元素的任何 Overlay 都將繼承此設置。

    <project>
        ...
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>3.3.2</version>
            <configuration>
              <dependentWarExcludes>WEB-INF/web.xml,index.*</dependentWarExcludes>
            </configuration>
           </plugin>
        </plugins>
        ...
    </project>
    
  • workDirectory 設置將臨時提取 Overlay 的目錄。

    <project>
        ...
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>3.3.2</version>
            <configuration>
              <!-- default value is target/war/work -->
              <workDirectory>/tmp/extract_here</workDirectory>
            </configuration>
           </plugin>
        </plugins>
        ...
    </project>
    

使用 Overlay 的 zip 依賴

要將 zip 依賴項用作 Overlay ,必須在插件的配置中顯式配置它。例如,要在 webappscripts 目錄中插入 zip Overlay 的內容,請執行以下操作:

<project>
    ...
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>3.3.2</version>
        <configuration>
          <overlays>
            <overlay>
              <groupId>zipGroupId</groupId>
              <artifactId>zipArtifactId</artifactId>
              <type>zip</type>
              <targetPath>scripts</targetPath>
            </overlay>
          </overlays>
        </configuration>
      </plugin>
    </plugins>
    ...
</project>

示例

引入外部資源

假設我們的項目結構如下:

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

上面的項目結構中包含了外部資源目錄:resource2。如果也想將這些外部資源打包到 WAR 包中,則可以借用 <webResources> 元素。

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>3.3.2</version>
        <configuration>
          <webResources>
            <resource>
              <!-- 下面是一個相對于pom.xml文件的目錄 -->
              <directory>resource2</directory>
            </resource>
          </webResources>
        </configuration>
      </plugin>
    </plugins>
  </build>
  ...
</project>

使用上面的 <webResources> 配置生成的結果如下:

documentedproject-1.0-SNAPSHOT.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
 |-- external-resource.jpg
 |-- image2
 |   `-- external-resource2.jpg
 |-- index.jsp
 `-- jsp
     `-- websource.jsp

external-resource2.jpgimage2 將復制到 WAR 的根目錄,保留目錄結構。

過濾資源文件

假設我們的項目結構如下(添加了一個 configurations 目錄):

 .
 |-- configurations
 |   |-- config.cfg
 |   `-- properties
 |       `-- config.prop
 |-- pom.xml
 |-- resource2
 |   |-- external-resource.jpg
 |   `-- image2
 |       `-- external-resource2.jpg
 `-- src
     `-- main
         |-- java
         |   `-- com
         |       `-- example
         |           `-- projects
         |               `-- SampleAction.java
         |-- resources
         |   `-- images
         |       `-- sampleimage.jpg
         `-- webapp
             |-- WEB-INF
             |   `-- web.xml
             |-- index.jsp
             `-- jsp
                 `-- websource.jsp

為了防止在啟用篩選時損壞二進制文件,可以配置一個不被篩選的文件擴展名列表。

        ...
        <configuration>
          <!-- the default value is the filter list under build -->
          <!-- specifying a filter will override the filter list under build -->
          <filters>
            <filter>properties/config.prop</filter>
          </filters>
          <!-- 指定不需要過濾的資源文件的擴展名 -->  
          <nonFilteredFileExtensions>
            <!-- 默認值包含jpg,jpeg,gif,bmp,png -->
            <nonFilteredFileExtension>pdf</nonFilteredFileExtension>
          </nonFilteredFileExtensions>
          <webResources>
            <resource>
              <directory>resource2</directory>
              <!-- 一般不會過濾二進制文件,否則可能會損壞二進制文件。所以,這里禁用過濾功能 -->
              <filtering>false</filtering>
            </resource>
            <resource>
              <directory>configurations</directory>
              <!-- 對文本類型的資源文件開啟過濾功能 -->
              <filtering>true</filtering>
              <excludes>
                <exclude>**/properties</exclude>
              </excludes>
            </resource>
          </webResources>
        </configuration>
        ...

假如 config.prop 的內容如下:

interpolated_property=some_config_value

假如 config.cfg 的內容如下:

<another_ioc_container>
    <configuration>${interpolated_property}</configuration>
</another_ioc_container>

生成的 WAR 包中的結構如下:

documentedproject-1.0-SNAPSHOT.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
 |-- config.cfg
 |-- external-resource.jpg
 |-- image2
 |   `-- external-resource2.jpg
 |-- index.jsp
 `-- jsp
     `-- websource.jsp

其中,WAR 包中 config.cfg 文件的內容如下:

<another_ioc_container>
   <configuration>some_config_value</configuration>
</another_ioc_container>

在 2.2 和更早版本的插件中,在過濾資源時使用的當前平臺的編碼。根據編碼方式的不同,過濾后的字符可能會亂碼。從 2.3 版本開始,該插件在過濾資源時使用project.build.sourceEncoding property 的值。一個值得注意的例外是 .xml 文件是使用的 xml 文件中指定的編碼進行過濾的。

覆蓋默認輸出目錄

默認情況下,Web 資源被復制到 WAR 的根目錄,如前一個示例所示。要覆蓋默認輸出目錄,請指定 targetPath

        ...
        <configuration>
          <webResources>
            <resource>
              ...
            </resource>
            <resource>
              <directory>configurations</directory>
              <!-- override the destination directory for this resource -->
              <targetPath>WEB-INF</targetPath>
              <!-- enable filtering -->
              <filtering>true</filtering>
              <excludes>
                <exclude>**/properties</exclude>
              </excludes>
            </resource>
          </webResources>
        </configuration>
        ...

如果使用上面的示例項目和插件配置,則產生的 WAR 如下所示:

documentedproject-1.0-SNAPSHOT.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
 |   |-- config.cfg
 |   `-- web.xml
 |-- external-resource.jpg
 |-- image2
 |   `-- external-resource2.jpg
 |-- index.jsp
 `-- jsp
     `-- websource.jsp

自定義 WAR 的清單文件

可以通過配置 WAR 插件的 archiver 來定制 WAR 包中的清單文件。有關可用的完整信息,請查看 Maven Archiver 的文檔

為 WAR 生成 Class-Path 清單項類似于為 JAR 生成 Class-Path 清單項,但有幾個細微的區別,因為通常情況下不希望同一個 JAR 同時出現在 Class-Path 清單項和 WEB-INF/lib 目錄中。下面是一個自定義 WAR 插件的歸檔配置:

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>3.3.2</version>
        <configuration>
          <archive>
            <manifest>
              <addClasspath>true</addClasspath>
            </manifest>
          </archive>
        </configuration>
      </plugin>
      ...
    </plugins>
  </build>
  ...
</project>

現在,您可以通過以下示例控制 WEB-INF/libClass-Path 清單項中包含哪些依賴項。Maven 將遵循可傳遞依賴關系樹,直到它到達范圍為 provided 的工件。注意:沒有辦法聲明一個依賴項僅包含在 WEB-INF/lib 中而不包含在 Class-Path 清單項中。

<project>
  ...
  <dependencies>
    <dependency>
      <groupId>org.foo</groupId>
      <artifactId>bar-jar1</artifactId>
      <version>${pom.version}</version>
      <optional>true</optional>
      <!-- goes in manifest classpath, but not included in WEB-INF/lib -->
    </dependency>
    <dependency>
      <groupId>org.foo</groupId>
      <artifactId>bar-jar2</artifactId>
      <version>${pom.version}</version>
      <!-- goes in manifest classpath, AND included in WEB-INF/lib -->
    </dependency>
    <dependency>
      <groupId>org.foo</groupId>
      <artifactId>bar-jar3</artifactId>
      <version>${pom.version}</version>
      <scope>provided</scope>
      <!-- excluded from manifest classpath, and excluded from WEB-INF/lib -->
    </dependency>
    ...
  </dependencies>
  ...
</project>

包括和排除 WAR 中的文件

通過使用 <packageIncludes><packageExcludes> 元素可以從 WAR 文件中包括或排除某些文件,這兩個元素都采用逗號分隔的 Ant 文件集模式列表。您可以使用 ** 等通配符來表示連續的多個目錄,使用 * 來表示單個文件名或單個目錄名中的部分字符。下面是一個從 WEB-INF/lib 中排除所有 JAR 文件的示例:

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-war-plugin</artifactId>
        <version>3.3.2</version>
        <configuration>
          <packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes>
        </configuration>
      </plugin>
    </plugins>
  </build>
  ...
</project>

有時,即使是這樣的通配符也是不夠的。在這些情況下,可以使用具有 %regex[] 語法的正則表達式。這里是一個實際的用例,我們希望排除任何 commons-logginglog4j 的 JAR 文件,但不希望排除 log4j-over-slf4j 的 JAR 文件。因此,我們希望排除 log4j-<version>.jar,但保留 log4j-over-slf4j-<version>.jar

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-war-plugin</artifactId>
        <version>3.3.2</version>
        <configuration>
          <!--
            Exclude JCL and LOG4J since all logging should go through SLF4J.
            Note that we're excluding log4j-<version>.jar but keeping
            log4j-over-slf4j-<version>.jar
          -->
          <packagingExcludes>
            WEB-INF/lib/commons-logging-*.jar,
            %regex[WEB-INF/lib/log4j-(?!over-slf4j).*.jar]
          </packagingExcludes>
        </configuration>
      </plugin>
    </plugins>
  </build>
  ...
</project>

使用文件名映射

可能需要自定義庫和 TLD 的文件名。默認情況下,使用以下模式存儲這些資源:

@{artifactId}@-@{version}@.@{extension}@

如果工件具有 classifier,那么默認模式為:

@{artifactId}@-@{version}@-@{classifier}@.@{extension}@

outputFileNameMapping 參數允許您提供自定義模式,模式中定義的每個標記將被當前工件中的一個值替換。您可以使用 ArtifactArtifactHandler 的任何屬性作為要代替的標記。還有一個名為 dashClassifier?。從 2.1 開始就可以使用。當且僅當工件具有 classifier 時,它才會添加字符串 -yourclassifier

例如,要存儲沒有版本號或 classifier 的庫和 TLD,請使用以下模式:

@{artifactId}@.@{extension}@

要存儲沒有版本號但帶有 classifier(如果存在)的庫和 TLD,請使用以下模式:

@{artifactId}@@{dashClassifier?}@.@{extension}@

創建瘦身的 WAR 包

在典型的 J2EE 環境中,WAR 打包在 EAR 中進行部署。WAR 可以在 WEB-INF/lib 中包含其所有依賴的 JAR,但是如果存在多個 WAR,由于存在重復的 JAR,EAR 可能會迅速變大。相反,J2EE 規范允許 WAR 通過 MANIFEST.MF 中的 Class-Path 設置引用 EAR 中打包的外部 JAR。

Maven EAR 插件直接支持創建瘦身的 WAR 包,這意味著也需要配置 Maven EAR 插件

您需要更改 EAR 項目的 pom.xml 以在 EAR 中打包這些所需要依賴的 JAR。注意,我們將所有內容打包到 EAR 中的 lib/ 目錄中。這只是個人用來區分 J2EE 模塊(將打包在 EAR 的根目錄中)和 Java 庫(打包在 lib/ 中)的一種方式。

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-ear-plugin</artifactId>
        <version>2.9.1</version>
        <configuration>
          <defaultLibBundleDir>lib/</defaultLibBundleDir>
          <skinnyWars>true</skinnyWars>
        </configuration>
      </plugin>
    </plugins>
  </build>
  ...
</project>

現在是痛苦的部分。您的 EAR 項目的 pom.xml 需要列出 WAR 的每個依賴項。這是因為 Maven 假設打包的是完整的 WAR 包,并且不包括 EAR 中其他 WAR 的可傳遞依賴項。

<project>
  ....
  <dependencies>
    <dependency>
      <groupId>com.acme</groupId>
      <artifactId>shared-jar</artifactId>
      <version>1.0.0</version>
    </dependency>
    <dependency>
      <groupId>com.acme</groupId>
      <artifactId>war1</artifactId>
      <version>1.0.0</version>
      <type>war</type>
    </dependency>
    <dependency>
      <groupId>com.acme</groupId>
      <artifactId>war2</artifactId>
      <version>1.0.0</version>
      <type>war</type>
    </dependency>
  </dependencies>
  ...
</project>

您的 EAR 將包含以下內容:

 .
 |-- META-INF
 |   `-- application.xml
 |-- lib
 |   `-- shared-jar-1.0.0.jar
 |-- war1-1.0.0.war
 `-- war2-1.0.0.war

下面是一個更完整的示例。

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>3.3.2</version>
    <configuration>
        <!-- 生成的WAR文件的目錄。默認為${project.build.directory} -->
        <outputDirectory>${project.build.directory}</outputDirectory>
        <!-- 用于在WAR中包含額外文件的單個目錄。這是您放置JSP文件的地方。。默認為${basedir}/src/main/webapp -->
        <warSourceDirectory>${basedir}/src/main/webapp</warSourceDirectory>
        <!-- 指定解壓形式的 WAR 的默認輸出目錄。默認為${project.build.directory}/${project.build.finalName}
            可以是外部servlet容器的部署目錄以便直接運行,比如Tomcat的webapps目錄 -->
        <webappDirectory>/your/apache-tomcat-x.x.xx/webapps/</webappDirectory>
        <!-- 將所依賴的 WAR 包解壓縮的輸出目錄(如果需要的話)。默認為${project.build.directory}/war/work -->
        <workDirectory>${project.build.directory}/war/work</workDirectory>
        
        <!-- Maven項目的默認資源目錄為src/main/resources,將會輸出到target/classes和WAR包中的WEB-INF/classes,并保留源資源目錄結構。
             <webResources>元素可以用來包含不在默認資源目錄中的資源文件 -->
        <webResources>
            <!-- 這里的<resource>元素與一般<resource>元素的用法相同 -->
            <resource>
                <!-- 下面是一個相對于pom.xml文件的目錄 -->
                <directory>resource2</directory>
                <!-- <includes>默認值為**,即包含所有文件。下面僅包含.jpg文件 -->
                <includes>
                    <include>**/*.jpg</include>
                </includes>
                <!-- <excludes>沒有默認值。下面排除路徑中包含image2的資源 -->
                <excludes>
                    <exclude>**/image2</exclude>
                </excludes>
            </resource>
            <!-- 另一個<resource>示例 -->
            <resource>
                <directory>resource2</directory>
                <includes>
                    <include>**/pattern1</include>
                    <include>*pattern2</include>
                </includes>
                <excludes>
                    <exclude>*pattern3/pattern3</exclude>
                    <exclude>pattern4/pattern4</exclude>
                </excludes>
            </resource>
        </webResources>
        <archive>
            <!-- 默認打成WAR時不包含pom.xml -->
            <addMavenDescriptor>false</addMavenDescriptor>
        </archive>
        <!-- 指定打成WAR時不包含的文件 -->
        <packagingExcludes>WEB-INF/jetty-*.xml</packagingExcludes>
    </configuration>
</plugin>
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,667評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容