先說結論:
1、強烈建議使用“/”開頭的路徑(Web應用程序特有的絕對路徑)
2、"/"具體又分為以下兩種情況
- 若"/"由客戶端發起的請求:稱為 Web服務器的根目錄
- “/”代表主機根目錄【
http://localhost:8080/
】 - 超鏈接、表單、重定向
- “/”代表主機根目錄【
- 若"/"由Servlet容器來處理:稱為 Web項目的虛擬目錄
- “/”代表【
http://localhost:8080/projectName/
】 - 轉發、包含、
- “/”代表【
3、不帶“/”的相對路徑,是相對於訪問到當前文件的路徑,而不是當前文件所在的目錄。
1. JavaWeb中的絕對、相對路徑
-
絕對路徑:
-
絕對路徑就是你的主頁上的文件或目錄在硬盤上真正的路徑,(URL和物理路徑),例如:C:\xyz\test.txt 代表了test.txt文件的絕對路徑。
-
Web絕對路徑指給出的訪問路徑可以准確定位到資源的路徑。
web應用的絕對路徑,是指待訪問協議的路徑,即URL。
例:
http://localhost:8080/Servlets/index.jsp
-
-
相對路徑:
相對路徑必須要結合參照路徑才可組成可以准確定位資源的絕對路徑。
絕對路徑 = 參照路徑 + 相對路徑
1.1 JavaWeb根路徑 / 的區別
① 對於服務端
來說,稱為 “WEB應用的虛擬路徑”:http://localhost:8080/projectName/
-
應用場景如:請求轉發,web.xml中的路徑url-pattern路徑配置,都是由web服務器來調用執行的。
-
請求轉發:
request.getRequestDispacter("/path/a.jsp").forward(request,response) :=>則物理地址:`http://localhost:8080/projectName/path/a.jsp`
-
web.xml文件中映射Servlet訪問路徑:
<servlet> <servlet-name>Step2Servlet</servlet-name> <servlet-class>Step2Servlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Step2Servlet</servlet-name> <url-pattern>/Step2Servlet</url-pattern> </servlet-mapping> <!-- 映射的物理地址:http://localhost:8080/projectName/Step2Servlet -->
-
-
說明:
http://localhost:8080/projectName/
中的projectName實際代表的是項目發布的虛擬目錄,虛擬目錄由以下情況配置:-
在MyEclipse開發項目中,虛擬目錄默認為項目名稱
-
而在IDEA中,則需要自己配置,具體見IDEA中發布JavaWeb項目
-
Tomcat配置虛擬目錄:在Tomcat下conf/server.xml中添加:
<Context docBase="F:\develop\upload\temp" path="/pic" reloadable="false"/> <!--其中 path="/pic" 即是 項目的虛擬路徑 -->
訪問
http://localhost:8080/pic
即可訪問F:\develop\upload\temp下的資料。
-
-
重點:request.getContextPath() =
http://localhost:8080/projectName/
② 對於由客戶端
來說 ,“/” 代表着的是web站點的根路徑
,即http://localhost:8080/
-
應用場景如:
a標簽
、表單提交
,請求重定向
- 超鏈接 : <a href="/testservlet"></a>=> `http://localhost:8080/testservlet` - form表單的action: <form action="/login.jsp"> =>` http://localhost:8080/login.jsp` - 做請求重定向的時候:response.sendRedirect("/a.jsp")=> `http://localhost:8080/a.jsp` 重定向資源是在servlet代碼中實現的,服務端是將要重定向的路徑返回給瀏覽器, 讓瀏覽器重新請求,也歸類為客戶端請求,和瀏覽器在頁面中發送請求的規律是一樣的
2. 強烈建議
考慮到項目的移植性,實際開發種,我們使用“/”開頭的路徑,具體如下:
項目名 testProject
2.1 JSP頁面到JSP頁面
- 相對路徑的方式:相對路徑是根據當前頁面的位置去定位目標的位置
該方法簡單,適合初學者,但實際項目種移植性不好。
<!--a.jsp=>b.jsp-->
<a href="b.jsp">轉向b</a>
<!--a.jsp=>c.jsp-->
<a href="jsp/c.jsp">轉向c</a>
<!--c.jsp=>a.jsp-->
<a href="../a.jsp">轉向a</a>
- 絕對路徑的方式(推薦使用):
<!--a.jsp=>b.jsp-->
<a hre="${pageContext.request.contextPath}/b.jsp">絕對轉向b</a>
<a hre="${request.getContextPath()}/b.jsp">絕對轉向b</a>
<!--a.jsp向c.jsp-->
<a hre="${pageContext.request.contextPath}/jsp/c.jsp">絕對轉向c</a>
<!--c.jsp向a.jsp-->
<a hre="${pageContext.request.contextPath}/a.jsp">絕對轉向a</a>
${pageContext.request.contextPath}的值:/testProject(獲取項目虛擬路徑,也就是項目發布名,虛擬路徑一般等同於項目名)
其中“/”表示的是Web服務器的根目錄,也就是http://localhost:8080
或則Tomcat的webapps/testProject 目錄,這是一個絕對路徑,不會出錯,移植性強。
2.2 JSP頁面到Servlet
實際上和jsp到jsp一樣.
假設現在在TestServelt
中 請求路徑為http://localhost:8080/testProject/servlet/testServlet
- 相對路徑的方式:
<!--a.jsp=>TestServlet-->
<a href="servlet/TestServlet">轉向TestServlet</a>
<!--c.jsp=>TestServlet-->
<a href="../servlet/TestServlet">轉向TestServlet</a>
- 絕對路徑的方式:(推薦使用)
<!--a.jsp=>TestServlet-->
<a href="${pageContext.request.contextPath}/servlet/TestServlet">轉向TestServlet</a>
<!--c.jsp=>TestServlet-->
<a href="${pageContext.request.contextPath}/servlet/TestServlet">轉向TestServlet</a>
2.3 Servlet發出的轉發
假設現在在TestServelt
中 請求路徑為http://localhost:8080/testProject/servlet/testServlet
假設現在在TestServelt2
中 請求路徑為http://localhost:8080/testProject/servlet/testServlet2
2.3.1 轉發到a.jsp :
- 相對路徑
request.getRequestDispatcher("../a.jsp").forword(request,response);
../相對於退出一級(servlet這一級),回到 http://localhost:8080/testProject這里 ,拼接上a.jsp即得到正確路徑url=http://localhost:8080/testProject/a.jsp,這是用的相對路徑.
- 絕對路徑(推介使用)
request.getRequestDispatcher("/a.jsp").forword(request,response);
這也可以實現正確跳轉,因為這里的"/"
表示web的虛擬路徑
即 http://localhost:8080/testProject
,拼接上a.jsp即得到正確的路徑url=http://localhost:8080/testProject/a.jsp ,這是絕對路徑。
2.3.2 轉發到Testservlet2:
-
相對路徑
request.getRequestDispatcher("testServlet2").forward(request,response);
TestServlet和TestServlet2在
同一層級
,這里用的是相對路徑
。 -
絕對路徑(推介使用)
request.getRequestDispatcher("/servlet/testServlet2").forward(request,response);
這里就是絕對路徑了,"/”表示
web虛擬路徑
2.4 Servlet發出的重定向
重定向其實同JSP頁面發起的請求一樣,因為是一次新的HTTP請求
// request.getContextPath() 獲取項目根路徑 /testProject
response.sendRedirect(request.getContextPath() + "/a.jsp");//正確
response.sendRedirect("/a.jsp"); //不正確
這種寫法是錯誤的 地址欄可見url=http://localhost:8080/a.jsp
, 因為這里的"/"
表示的是web虛擬路徑,即:http://localhost:8080
2.5 絕對路徑使用小結(重點)
在實際Java Web開發中,我們使用以下方法描述路徑:使用“/”開頭的絕對路徑
-
客戶端發起的請求,包括以下情景:超鏈接、表單、重定向等,在代碼中使用request.contextPath()方法獲取下項目虛擬路徑,http://localhost:8080/虛擬目錄(項目發布目錄,一般為項目名稱),可以理解該目錄為項目根目錄,然后訪問其他文件,相對該路徑描述出來即可。
-
本案例的request.contextPath()獲取的路徑為:http://localhost:8080/testProject
<!--a.jsp=>b.jsp--> <a hre="${request.getContextPath()}/b.jsp">絕對轉向b</a> //拼接出來的實際url=http://localhost:8080/testProject/b.jsp
<!--a.jsp=>TestServlet--> <a href="${request.getContextPath()}/servlet/TestServlet">轉向TestServlet</a> //拼接出來的實際url=http://localhost:8080/testProject/servlet/TestServlet
// request.getContextPath() 獲取項目虛擬目錄 /testProject response.sendRedirect(request.getContextPath() + "/a.jsp");//正確 //拼接出來的實際url=http://localhost:8080/testProject/a.jsp
-
服務器轉發或包含,由一個Servlet轉發到另一個Servlet 或 JSP,這是在服務器內完成,而不是由客戶端發起的請求,包括場景:轉發、包含、
等. request.getRequestDispatcher("/jsp/c.jsp").forword(request,response); //拼接出來的實際url=http://localhost:8080/testProject/jsp/c.jsp
request.getRequestDispatcher("/servlet/testServlet2").forward(request,response); //拼接出來的實際url=http://localhost:8080/testProject/servlet/testServlet2
這么多路徑,搞暈了嗎?暈了就對了,說明你還由很多東西需要學習!