WAR 插件負責收集 Web 應用程序的所有依賴項、類和資源,并將它們打包到 WAR 包中,僅包含 scope
為 compile+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 插件的一般方式。需要解析 scope
為 compile+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 package
或 mvn 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>
:不應篩選的文件擴展名列表。將在篩選webResources
和overlays
時使用。<outdatedCheckPath>
:將根據過期內容檢查的資源的路徑前綴。從 3.3.2 開始,如果指定了/
值,則將檢查整個webappDirectory
,即/
表示根目錄。默認為WEB-INF/lib/
。<outputFileNameMapping>
:復制庫和 TLD 時要使用的文件名映射。如果未設置文件映射(默認),則將使用文件的標準名稱復制文件。。<outputTimestamp>
:可重復輸出存檔項的時間戳,格式為 ISO 8601yyyy-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。需要解析 scope
為 runtime
的依賴項,默認綁定到 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
目標的全部參數
需要解析 scope
為 runtime
的依賴項,默認綁定到 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
。 -
targetPath
:webapp
結構中的目標相對路徑,僅適用于 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,沒有 groupId
、artifactId
。如果需要首先應用 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 ,必須在插件的配置中顯式配置它。例如,要在 webapp
的 scripts
目錄中插入 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.jpg
和 image2
將復制到 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/lib
和 Class-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-logging
和 log4j
的 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
參數允許您提供自定義模式,模式中定義的每個標記將被當前工件中的一個值替換。您可以使用 Artifact
和 ArtifactHandler
的任何屬性作為要代替的標記。還有一個名為 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>