Maven 編碼指南
一、概述
在本教程中,我們將學習如何在 Maven 中設置字符編碼。
我們將展示如何為一些常見的 Maven 插件設置編碼。
此外,我們將了解如何在項目級別以及通過命令行設置編碼。
2. 什麼是編碼,我們為什麼要關心?
世界上有許多不同的語言使用不同的字符。
一種稱為 Unicode 的字符映射系統擁有超過 100,000 個字符、符號甚至表情符號(表情符號)。
為了不使用大量內存,我們使用稱為編碼的映射系統在位和字節之間轉換字符,以及屏幕上的人類可讀字符。
現在有很多編碼系統。要讀取文件,我們必須知道使用哪種編碼系統。
2.1。如果我們不在 Maven 中聲明編碼會發生什麼?
Maven 認為編碼足夠重要,如果我們不聲明編碼,它就會退出警告。
事實上,這個警告佔據了 Apache Maven 站點上常見問題頁面的第一名。
要看到這個警告,讓我們在構建中添加幾個插件。
首先,讓我們添加maven-resources-plugin
,它將資源複製到輸出目錄中:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.2.0</version>
</plugin>
我們還想編譯我們的代碼文件,所以讓我們添加maven-compiler-plugin
:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
當我們在一個多模塊項目中工作時,父 POM 可能已經為我們設置了編碼。出於演示目的,讓我們通過覆蓋它來清除 encoding 屬性(別擔心,我們稍後會回到這個):
<properties>
<project.build.sourceEncoding></project.build.sourceEncoding>
</properties>
讓我們使用標準的 Maven 命令運行插件:
mvn clean install
像這樣取消設置我們的編碼可能會破壞構建!我們將在日誌中看到我們收到以下警告:
[INFO] --- maven-resources-plugin:3.2.0:resources (default-resources) @ maven-properties ---
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, ie build is platform dependent!
警告指出,如果未指定編碼系統,Maven 將使用平台默認值。
通常在 Windows 上,默認值為Windows-1252 (又名 CP-1252,或 Cp1252)。
此默認值可能會根據本地環境而更改。我們將在下面看到如何從構建中刪除此平台依賴項。
2.2.如果我們在 Maven 中聲明一個不正確的編碼會發生什麼?
Maven 是一個需要能夠讀取源文件的構建工具。
為了讀取源文件, Maven 必須設置為使用與源文件編碼相同的編碼。
Maven 還生成通常分發到另一台計算機的文件。因此,使用預期的編碼編寫輸出文件很重要。未採用預期編碼的輸出文件可能無法在其他系統上讀取。
為了展示這一點,讓我們添加一個使用非 ASCII 字符的簡單 Java 類:
public class NonAsciiString {
public static String getNonAsciiString() {
String nonAsciiŞŧř = "ÜÝÞßàæç";
return nonAsciiŞŧř;
}
}
在我們的 POM 中,讓我們將構建設置為使用ASCII編碼:
<properties>
<project.build.sourceEncoding>US-ASCII</project.build.sourceEncoding>
</properties>
使用mvn clean install
運行它,我們看到我們得到了許多如下形式的構建錯誤:
[ERROR] /Baeldung/tutorials/maven-modules/maven-properties/src/main/java/
com/baeldung/maven/properties/NonAsciiString.java:[15,31] unmappable character (0xC3) for encoding US-ASCII
我們看到這一點是因為我們的文件包含非 ASCII 字符,因此無法通過 ASCII 編碼讀取它們。
在可能的情況下,最好保持簡單並避免使用非 ASCII 字符。
在下一節中,我們將看到將 Maven 設置為使用UTF-8編碼以避免任何問題也是一個好主意。
3. Maven配置中如何設置編碼?
首先,讓我們看看我們如何在插件級別設置編碼。
然後我們將看到我們可以設置項目範圍的屬性。這意味著我們不需要在每個插件中聲明編碼。
3.1。我們如何在 Maven 插件中設置encoding
參數?
大多數插件都帶有一個encoding
參數,這使得這非常簡單。
我們需要在maven-resources-plugin
和maven-compiler-plugin
中設置編碼。我們可以簡單地將encoding
參數添加到我們的每個 Maven 插件中:
<configuration>
<encoding>UTF-8</encoding>
</configuration>
讓我們使用mvn clean install
運行此代碼並查看日誌記錄:
[INFO] --- maven-resources-plugin:3.2.0:resources (default-resources) @ maven-properties ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
我們可以看到插件現在使用 UTF-8,並且我們已經解決了上面的警告。
3.2.我們如何在 Maven 構建中設置項目範圍的encoding
參數?
記住為我們聲明的每個插件設置一個編碼是非常麻煩的。
值得慶幸的是,大多數 Maven 插件使用相同的全局 Maven 屬性作為其encoding
參數的默認值。
正如我們之前看到的,讓我們從插件中刪除encoding
參數並設置:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
運行我們的構建會產生與我們在上面看到的相同的 UTF-8 日誌記錄行。
在多模塊項目中,我們通常會在父 POM 中設置此屬性。
此屬性將被設置的任何插件特定屬性覆蓋。
重要的是要記住插件沒有義務使用這個屬性。例如, maven-war-plugin
的早期版本 (<2.2) 會忽略此屬性。
3.3.我們如何為報告插件設置項目範圍的encoding
參數?
也許令人驚訝的是,我們必須設置兩個屬性以保證我們已經為所有情況設置了項目範圍的編碼。
為了說明這一點,我們將使用[properties-maven-plugin](https://www.mojohaus.org/properties-maven-plugin/) :
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.1.0</version>
</plugin>
讓我們還將一個新的系統範圍屬性設置為空:
<project.reporting.outputEncoding></project.reporting.outputEncoding>
如果我們現在運行mvn clean install
,我們的構建將失敗並顯示日誌:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-pmd-plugin:3.13.0:pmd (pmd) on project maven-properties: Execution pmd of goal
org.apache.maven.plugins:maven-pmd-plugin:3.13.0:pmd failed: org.apache.maven.reporting.MavenReportException: : UnsupportedEncodingException -> [Help 1]
即使我們設置了project.build.sourceEncoding
,這個插件也使用了不同的屬性。要理解為什麼會這樣,我們必須了解 Maven 構建配置和 Maven 報告配置之間的區別。
插件可以在使用單獨的屬性鍵的構建過程或報告過程中使用。
這意味著僅設置project.build.sourceEncoding
是不夠的。我們還需要為報告流程添加以下屬性:
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
建議在項目範圍內設置這兩個屬性。
3.4.我們如何在命令行上設置 Maven 編碼?
我們可以通過命令行參數設置屬性,而無需向 POM 文件添加任何配置。我們可能會這樣做,因為我們沒有對 pom.xml 文件的寫訪問權限。
讓我們運行以下命令來指定構建應該使用的編碼:
mvn clean install -Dproject.build.sourceEncoding=UTF-8 -Dproject.reporting.outputEncoding=UTF-8
命令行參數覆蓋任何現有配置。
因此,即使我們刪除了 pom.xml 文件中設置的任何編碼屬性,這也允許我們成功運行構建。
4. 在同一個 Maven 項目中使用多種類型的編碼
在項目中使用單一類型的編碼是個好主意。
但是,我們可能不得不在同一個構建中處理多種類型的編碼。例如,我們的資源文件可能有不同的編碼系統,這可能超出我們的控制範圍。
我們有辦法做到這一點嗎?好吧,這取決於情況。
我們看到我們可以逐個插件設置encoding
參數。因此,如果我們需要 CP-1252 中的代碼但想要以 UTF-8 輸出測試結果,那麼我們可以做到這一點。
我們甚至可以通過使用不同的執行在同一個插件中使用多種類型的編碼。
特別是,我們之前看到的maven-resources-plugin
內置了額外的功能。
我們之前看到了encoding
參數。該插件還提供了propertiesEncoding
參數以允許以與其他資源不同的方式對屬性文件進行編碼:
<configuration>
<encoding>UTF-8</encoding>
<propertiesEncoding>ISO-8859-1</propertiesEncoding>
</configuration>
當使用mvn clean install
運行構建時,這給出:
[INFO] --- maven-resources-plugin:3.2.0:resources (default-resources) @ maven-properties ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Using 'ISO-8859-1' encoding to copy filtered properties files.
在研究插件如何使用編碼時,總是值得參考maven.apache.org上的技術文檔。
5. 結論
在本文中,我們看到聲明編碼有助於確保代碼在任何環境中以相同的方式構建。
我們看到我們可以在插件級別設置編碼參數。
然後,我們了解到可以在項目級別設置兩個屬性。它們是project.build.sourceEncoding
和project.reporting.outputEncoding.
我們還看到可以通過命令行傳入編碼。這允許我們在不編輯 Maven POM 文件的情況下設置編碼類型。
最後,我們研究瞭如何在同一個項目中使用多種類型的編碼。
與往常一樣,示例項目在 GitHub 上可用。