| 路徑類型 | 定義 | 典型範例 |
|---|---|---|
| 絕對路徑 | 資源在伺服器檔案系統或 URL 中的完整路徑 | C:\app\config.properties、https://host/app/resource |
| 相對路徑 | 相對於某個基準目錄的路徑 | ./config、../lib、/webapp/resource |
關鍵區別:Servlet/JSP 中的相對路徑由伺服器端解析(相對於 Web 應用根目錄 /contextPath),而 HTML/JS/Form 中的相對路徑由瀏覽器客戶端解析(相對於網域根目錄 /)。
// 正確:以 "/" 開頭表示相對於 Web 應用根目錄
request.getRequestDispatcher("/user/a.jsp").forward(req, resp);
// 錯誤:不以 "/" 開頭會相對於當前 Servlet 路徑,極易出錯
request.getRequestDispatcher("user/a.jsp").forward(req, resp);
// 必須包含 contextPath,否則相對於網域根目錄
response.sendRedirect(request.getContextPath() + "/user/a.jsp");
// 或手動硬編碼(不推薦,部署路徑變更即失效)
response.sendRedirect("/myapp/user/a.jsp");
<!-- 必須加上 contextPath -->
<form action="<%=request.getContextPath()%>/handleServlet" method="post">
<a href="<%=request.getContextPath()%>/css/style.css">樣式</a>
<script src="<%=request.getContextPath()%>/js/main.js"></script>
<link rel="stylesheet" href="<%=request.getContextPath()%>/css/main.css">
<img src="<%=request.getContextPath()%>/images/logo.png">
最佳實踐:在 JSP 頁面頂部定義基準路徑變數,全頁複用:
<% String basePath = request.getContextPath(); %>
<base href="<%=request.getScheme()%>://<%=request.getServerName()%>:<%=request.getServerPort()%><%=basePath%>/">
| 場景 | JSP / Servlet 通用 | Servlet 專用 |
|---|---|---|
| Web 應用絕對路徑(部署目錄) | application.getRealPath("/") |
servletConfig.getServletContext().getRealPath("/") |
| 當前請求 URI(含 contextPath) | request.getRequestURI() |
request.getRequestURI() |
| 當前 Servlet 映射路徑 | — | request.getServletPath() |
| Context Path | request.getContextPath() |
request.getContextPath() |
// 獲取類所在目錄(含 package 結構)
MyClass.class.getResource("") // file:/path/to/classes/com/pkg/
MyClass.class.getResource("/") // file:/path/to/classes/ (classpath 根)
// 獲取資源流(推薦,打包成 JAR 也能用)
MyClass.class.getResourceAsStream("/config.properties")
Thread.currentThread().getContextClassLoader().getResourceAsStream("config.properties")
| 容器 | System.getProperty("user.dir") | 推薦做法 |
|---|---|---|
| Tomcat | $CATALINA_HOME/bin | 統一使用 ClassLoader.getResourceAsStream() 讀取 WEB-INF/classes 下資源 |
| WebLogic | WebLogic 安裝根目錄 | |
| Resin | JSP 編譯產生的 Servlet 目錄 |
resourceLoader.getResource("classpath:config.yml") 統一訪問 classpath、檔案系統、URL 資源。@PropertySource、@ConfigurationProperties 綁定外部配置,啟動時指定 --spring.config.location=file:/etc/app/。server.xml 或 web.xml 配置 Context docBase,將外部目錄掛載到 Web 應用路徑下。new File("relative/path") —— 相對於 JVM 啟動目錄,容器環境下極不穩定request.getRequestDispatcher("no-leading-slash") —— 相對於當前請求路徑,重構時極易斷裂../../resource —— 檔案移動即失效,維護噩夢/myapp/ —— 部署時若 contextPath 變更全站掛掉Java Web 路徑問題的本質是「伺服器端視角」與「客戶端視角」的不一致。掌握核心原則:
/ 開頭的絕對路徑(相對於 contextPath)${pageContext.request.contextPath}ClassLoader.getResourceAsStream() 走 classpath 機制遵循這四條鐵律,可徹底杜絕路徑相關的 90% 部署故障與維護陷阱。