在 JSP/Servlet 專案中,從 WebRoot/index.jsp 要 forward 到 WebRoot/admin/main.jsp,許多開發者直覺寫 /admin/main.jsp 卻報 404。這篇文章釐清「相對路徑」與「絕對路徑」在 RequestDispatcher 中的真實行為。
// 錯誤:以 / 開頭被視為 Web 應用程式根目錄(Context Root)
request.getRequestDispatcher("/admin/main.jsp").forward(request, response);
若專案部署在 https://localhost:8080/myapp/,上述路徑會解析為 /myapp/admin/main.jsp。但若 admin 資料夾實際位於 WebRoot/admin/,則正確路徑應為 admin/main.jsp(不以 / 開頭)。
| 寫法 | 解析基準 | 適用場景 |
|---|---|---|
/admin/main.jsp | Context Root(專案根目錄) | 跨資料夾、統一入口 |
admin/main.jsp | 當前請求的資料夾(Relative to current request) | 同層或子資料夾 |
../other.jsp | 當前請求的上一層 | 返回上層目錄 |
contextPath,拼接完整路徑,避免相對路徑隨呼叫層級改變而出錯。
String path = request.getContextPath() + "/admin/main.jsp";
request.getRequestDispatcher(path).forward(request, response);
admin 資料夾確實在 WebRoot(或 src/main/webapp)下,而非 WEB-INF 內(後者不可直接存取)。forward:伺服器端跳轉,瀏覽器 URL 不變,共享同一個 request 物件。sendRedirect:客戶端跳轉,瀏覽器 URL 改變,發起新請求,需用絕對 URL 或以 / 開頭的 Context Root 路徑。JSP 轉發路徑的關鍵在於「以 / 開頭 = Context Root 絕對路徑;不以 / 開頭 = 相對當前請求路徑」。養成使用 request.getContextPath() 拼接完整路徑的習慣,能徹底杜絕部署環境變更導致的 404 錯誤。