首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java Web 相對路徑與絕對路徑完全指南:Servlet、JSP、前端資源統一解決

     編輯:Java 相關知識

前言

「為什麼 request.getRequestDispatcher(\"a.jsp\") 能跳轉,但 <a href=\"a.jsp\"> 卻 404?」路徑問題是 Java Web 開發的「隱形殺手」。本文從服務端/客戶端雙視角,系統梳理 /、./、../、contextPath 的語義差異,給出統一最佳實踐。

一、核心概念釐清

術語含義示例
Context Path (上下文路徑)Web 應用在容器中的路徑前綴/myapp (ROOT 應用為空串)
Servlet Path匹配 @WebServlet/web.xml 的路徑部分/user/login
Request URI完整請求路徑 (含 Context Path)/myapp/user/login
Real Path服務器文件系統物理路徑C:\tomcat\webapps\myapp\user\login.jsp

二、服務端路徑解析規則 (Servlet/JSP/Filter)

1. request.getRequestDispatcher(path) / jsp:forward

  • 以 / 開頭:相對於 Context Path (Web 應用根目錄)。
    request.getRequestDispatcher(\"/user/a.jsp\") → /myapp/user/a.jsp
  • 不以 / 開頭:相對於 當前請求的 Servlet Path 目錄。
    當前 /myapp/admin/index.jsp → request.getRequestDispatcher(\"a.jsp\") → /myapp/admin/a.jsp

2. response.sendRedirect(path) / location.href

  • 瀏覽器端跳轉,**必須包含 Context Path**。
  • 推薦:response.sendRedirect(request.getContextPath() + \"/user/a.jsp\")。
  • 或 JSP 中:<c:url value=\"/user/a.jsp\"/> (JSTL 自動補全 Context Path)。

3. 獲取物理路徑 (文件上傳/模板讀取)

// Servlet
String realPath = getServletContext().getRealPath("/upload"); // → /tomcat/webapps/myapp/upload

// JSP
String realPath = application.getRealPath("/upload");

// Spring Controller
@Autowired ServletContext servletContext;
String realPath = servletContext.getRealPath("/upload");

⚠️ WAR 包部署/爆炸部署差異:getRealPath 可能返回 null (未爆炸部署),**避免依賴物理路徑**,改用 ServletContext.getResourceAsStream() 讀取 classpath/resource 目錄資源。

三、客戶端路徑解析規則 (HTML/JS/CSS/圖片)

  • 瀏覽器**完全不知道** Context Path 概念,只認 HTTP 請求路徑。
  • 頁面地址:https://host:port/myapp/page.jsp
  • <a href=\"user/a.jsp\"> → 請求 /myapp/user/a.jsp (相對於頁面目錄)。
  • <a href=\"/user/a.jsp\"> → 請求 /user/a.jsp (相對於**域名根路徑**,丟失 Context Path → 404)。
  • <a href=\"${pageContext.request.contextPath}/user/a.jsp\"> → 正確請求 /myapp/user/a.jsp。

四、統一最佳實踐:模板/標籤輸出路徑

1. JSP + JSTL (推薦)

<%@ taglib prefix=\"c\" uri=\"https://java.sun.com/jsp/jstl/core\" %>
<a href=\"<c:url value='/user/a.jsp'/>\"">鏈接</a>
<script src=\"<c:url value='/js/app.js'/>\""></script>
<form action=\"<c:url value='/api/login'/>\"" method=\"post\">

2. Thymeleaf / FreeMarker / Velocity


<a th:href=\"@{/user/a.jsp}\">
<script th:src=\"@{/js/app.js}\">


<a href=\"${base}/user/a.jsp\">  // base = contextPath

3. 純前端項目 (Vue/React + Nginx 反向代理)

  • 構建時設置 publicPath: '/myapp/' (Webpack/Vite)。
  • Nginx location /myapp/ { proxy_pass ...; } 透傳。
  • 路由模式用 history + basename: '/myapp' (React Router) / base: '/myapp/' (Vue Router)。

五、常見坑點速查表

場景錯誤寫法正確寫法原因
JSP 引用 CSS/JS<link href=\"/css/style.css\"><c:url value=\"/css/style.css\"/>瀏覽器請求到域名根路徑,丟失 Context Path
Servlet forwardrd.forward(\"../a.jsp\")rd.forward(\"/a.jsp\")服務端不支持 ../ 相對父目錄
redirect 丟失參數resp.sendRedirect(\"a.jsp?id=1\")resp.sendRedirect(ctx+\"a.jsp?id=1\")相對路徑基於當前請求 URL,易出錯
獲取上傳文件真實路徑new File(request.getParameter(\"path\"))servletContext.getRealPath(\"/upload\") + File.separator + filename客戶端路徑對服務端無意義

六、Spring Boot 靜態資源映射

# application.yml
spring:
  web:
    resources:
      static-locations: classpath:/static/,classpath:/public/
  mvc:
    static-path-pattern: /static/**
  • 訪問 https://host:port/myapp/static/js/app.js 自動映射到 resources/static/js/app.js。
  • 模板引擎自動解析 @{/static/...}。

七、總結

  1. 服務端:/ = Context Path 根,getRequestDispatcher 用絕對路徑 /xxx。
  2. 客戶端:所有輸出到頁面的 URL 必須帶上 Context Path,用 c:url / th:href / publicPath 自動化。
  3. 物理路徑:getRealPath 不可靠,優先用 getResourceAsStream 讀取 classpath 資源。

路徑無小事,統一規範,告別 404。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved