專案中讀取配置檔、模板、圖片等資源時,路徑處理錯誤是高頻 Bug 來源。本文系統整理 ClassLoader、Class、ServletContext 等多種獲取路徑的方式,並給出避坑指南。
| 方法 | 返回值範例 | 適用場景 |
|---|---|---|
ThisClass.class.getResource("") | file:/.../classes/com/pkg/ | 當前類同包資源(不含類檔) |
ThisClass.class.getResource("/") | file:/.../classes/ | Classpath 根目錄 |
Thread.currentThread().getContextClassLoader().getResource("") | file:/.../classes/ | 當前執行緒上下文 ClassLoader 根(推薦通用) |
ThisClass.class.getClassLoader().getResource("") | file:/.../classes/ | 載入當前類的 ClassLoader 根 |
ClassLoader.getSystemResource("") | file:/.../classes/ | 系統 ClassLoader 根(應用程式啟動 classpath) |
ServletContext.getRealPath("/") | /opt/tomcat/webapps/ROOT/ | Web 應用部署根目錄(僅 Web 容器) |
Class.getResource("name") → 相對於**當前類包**解析(不以 / 開頭)。Class.getResource("/name") → 相對於**classpath 根**解析(以 / 開頭)。ClassLoader.getResource("name") → **永遠相對於 classpath 根**,不接受 / 開頭。// 假設類位於 /home/popeye/testjava/build/classes/net/...
URL base = ThisClass.class.getResource(""); // 獲取類所在目錄
File configFile = new File(base.getFile(), "../../../config/app.properties");
String absolutePath = configFile.getCanonicalPath(); // /home/popeye/testjava/config/app.properties
@WebServlet("/init")
public class InitServlet extends HttpServlet {
@Override
public void init() {
String webRoot = getServletContext().getRealPath("/"); // 部署根目錄
File config = new File(webRoot, "WEB-INF/config/app.properties");
// 後續讀取 config...
}
}
System.getProperty("user.dir") —— 工作目錄隨啟動方式變化,極不穩定。File 時用 toURI() 避免空格編碼問題。src/main/resources(Maven 標準),以 classpath:xxx 統一引用。D:/data/...),專案無法移植。ClassLoader.getResource,確保測試環境一致。getResource("") 行為可能不同,以 java -cp 命令列驗證為準。File 讀取,必須用 getResourceAsStream。ResourceLoader 工具類,集中管理路徑解析邏輯。