JavaWEB路徑總結,javaweb路徑
這篇文章是小編一直想寫的一篇,主要是對web階段中各個路徑進行的一些總結,希望讀者看過之後對於路徑方面有一個清晰的認識。首先聲明一點:世界上一切東西都是相對的,對於這點而言,相信大家並不陌生,從初中開始我們就接觸了物體的相對運動,由於這篇文章是針對於WEB階段來講的,所以以下絕對路徑和相對路徑都是針對於整個互連網而言的。
用戶端路徑
是指運行在瀏覽器上的路徑。比如:表單、超連結、js(location.href)、Ajax(url)、CSS和JS的引入以及重新導向等。路徑分為絕對路徑和相對路徑,相對路徑又分為相對主機的路徑和相對於當前請求的路徑。幹說沒用,舉例如下:
例1:假設a.html的路徑為: http://localhost:8080/hello/pages/a.html 。a.html的內容如下:
<a href="http://localhost:8080/hello/pages/b.html">絕對路徑</a><a href="/hello/pages/b.html">相對於主機的路徑</a><a href="b.html">相對於請求的路徑</a>
絕對路徑(以協議開頭的路徑):最終請求路徑為:http://localhost:8080/hello/pages/b.html
相對路徑:
相對於主機的路徑(以“/”開頭):相對於當前主機(可以簡單理解為ip地址,如果想深入瞭解請研究tomcat的Server.xml檔案。這裡是localhost)的路徑,請求的最終路徑為:http://localhost:8080/hello/pages/b.html
相對於請求的路徑(不以“/”開頭):相對於當前請求(瀏覽器的請求)的路徑,如果是直接存取的a.html頁面,則當前請求為:http://localhost:8080/hello/pages/a.html .最終請求路徑為:http://localhost:8080/hello/pages/b.html ;如果是請求的http://localhost:8080/hello/aServlet 然後在伺服器轉寄到了a.html頁面。則當前請求為:http://localhost:8080/hello/aServlet,請求的最終路徑為:http://localhost:8080/hello/b.html
例2:假設當前請求為http://localhost:8080/hello/aServlet。當前請求的Servlet(或Controller)中有如下重新導向的代碼:
//絕對路徑response.sendRedirect("http:localhost:8080/hello/page/b.html");//以“/”開頭的相對路徑response.sendRedirect("/hello/page/b.html");//不以“/”開頭的相對路徑response.sendRedirect("b.html");
絕對路徑是以協議開頭的,沒什麼可說的。
以“/”開頭的相對路徑(相對於當前主機的路徑):請求的最終路徑為:http://localhost:8080/hello/pages/b.html
不以“/”開頭的路徑(相對於當前請求的路徑):請求的最終路徑為:http://localhost:8080/hello/b.html
註:
1. 推薦使用相對於主機的路徑。這樣跟當前請求無關。
2. 重新導向是在伺服器上設定了302的狀態代碼和location的回應標頭。瀏覽器接收之後按照location的回應標頭重新發送請求,由於重新導向的地址是在用戶端重新請求的地址,所以重新導向屬於用戶端路徑。
服務端路徑
服務端路徑是指在伺服器上面啟動並執行請求,比如請求轉寄(常用)、請求包含等。服務端的路徑有兩種:相對於當前應用的路徑和相對於當前請求的路徑。
例:假設當前請求的路徑為:http://localhost:8080/hello/servlet/aServlet ,在後台有如下代碼:
//以“/”開頭,相對於當前應用的路徑request.getRequestDispatcher("/servlet/b.html").forward(request, response);//不以“/”開頭,相對於當前請求的路徑request.getRequestDispatcher("b.html").forward(request, response);
相對於當前應用的路徑(以“/”開頭):最終轉寄的地址為:http://localhost:8080/hello/servlet/b.html 。
相對於當前請求的路徑(不以“/”開頭):最終轉寄的地址為:http://localhost:8080/hello/servlet/b.html 。
另:所有Web層架構的底層使用的都是Web的基礎Filter(Struts)或Servlet(SpringMVC),請求都是request,響應都是response,所以各個Web層架構的轉寄或重新導向底層都是利用request和response進行的。
<url-pattern>路徑
這裡的路徑僅僅是指web.xml檔案中的標籤內容。這個路徑是虛擬路徑,只有相對路徑(相對於當前應用的路徑),但相對路徑的寫法可以是精確查詢和模糊查詢。
例:
<!—精確查詢,是相對於當前應用--><url-pattern>/servlet/testPath</url-pattern><!—模糊查詢,表示匹配servlet目錄下的所有檔案或請求。/*表示匹配所有--><url-pattern>/servlet/*</url-pattern><!—模糊查詢,表示匹配所有尾碼名為do的檔案或請求--><url-pattern>*.do</url-pattern>
在web.xml檔案中萬用字元(*)只能放在路徑開頭或結尾,不能放在中間。如“/*.do”是非法的。
註:tomcat尋找路徑的順序:優先具體的路徑,其次是匹配目錄,然後是尾碼名。最後是預設路徑。
擷取資源的路徑
擷取資源的路徑主要有3種,分別是ServletContext、Class和ClassLoader。其中ServletContext是WEB階段的,Tomcat提供的一種擷取資源的方式;Class和ClassLoader擷取資源主要是JavaAPI提供的一種擷取流的方式,由於這是JDK提供的,所以不僅局限於Web,在普通Java類中也可以使用,主要用於擷取src目錄及其子目錄下的檔案流。
ServletContext擷取資源的路徑。
這裡ServletContext擷取資源的路徑是相對系統的絕對路徑(在Windows中是帶盤符的,可以用來擷取上傳或下載檔案的具體路徑)。
基本文法:servletContext.getRealPath("路徑");參數中的路徑必須是相對路徑,可以“/”開頭,也可以不使用“/”開頭,但無論是否使用“/”開頭都是相對當前應用路徑,建議以"/"開頭(這樣可以盡量統一)。
另外擷取ServletContext的方法如下:
樣本如下:假如當前tomcat的路徑為:D:\SoftWare\development\tomcat7.0.52,項目名為hello。有如下代碼:
ServletContext servletContext = this.getServletContext();String path1 = servletContext.getRealPath("a.txt");String path2 = servletContext.getRealPath("/a.txt");
則path1和path2一樣:D:\SoftWare\development\tomcat7.0.52\webapps\hello\a.txt
所代表的網路路徑為:http://localhost:8080/hello/a.txt
Class擷取資源
Class擷取資源主要是用作自己寫的設定檔,用來讀取內容。
用法:clazz.getResourceAsStream("路徑")。參數中的路徑可以以“/”開頭,也可以不以“/”開頭。其中帶“/”的表示相對於當前類的路徑,不以“/”開頭表示相對於當前class所在目錄的路徑。
樣本:假設當前類的包結構為:com.wind-snow.test.path
//擷取Class對象Class clazz = this.getClass();//帶“/”的路徑(相對於當前的類路徑)InputStream stream1 = clazz.getResourceAsStream("/a.txt");//不帶“/”的路徑(相對於當前class所在目錄的路徑)InputStream stream2 = clazz.getResourceAsStream("a.txt");
stream1代表src目錄下的a.txt檔案,發布之後代表“/項目名/WEB-INF/classes/a.txt”檔案。
stream2代表src目錄下的com/wind-snow/test/path/a.txt檔案,發布之後代表“/項目名/WEB-INF/classes/com/wind-snow/test/path/a.txt”檔案。
註:
1. 若找不到。此方法不會報異常。只是會返回一個null;。
2. 這個方法的底層使用的是ClassLoader的getResourceAsStream方法。
ClassLoader擷取資源
和Class擷取資源類似。只是不同的寫法而已,也是用於擷取檔案流的。
用法:classLoader.getResourceAsStream("路徑")。參數中的路徑可以以“/”開頭,也可以不以“/”開頭(建議)。但帶不帶“/”的都表示相對於當前類的路徑。
樣本:假設當前類的路徑為:com.wind-snow.test.path
ClassLoader classLoader= this.getClass().getClassLoader();InputStream stream1 = classLoader.getResourceAsStream("/a.txt");InputStream stream2 = classLoader.getResourceAsStream("a.txt");
stream1和stream2都代表src目錄下的a.txt檔案,發布之後代表“/項目名/WEB-INF/classes/a.txt”檔案。
註:若找不到。此方法不會報異常。只是會返回一個null。
總結:
1. 用戶端是帶“/”相對當前主機。
2. 服務端(包括上述的服務端、url-pattern路徑和ServletContext路徑)帶不帶“/”都是相對當前應用(建議帶上)。
3. Class帶“/”是相對當前類路徑。不帶“/”是相對於當前位置。
4. ClassLoader無論帶不帶“/”都是當前類路徑(建議帶上)。
另附:總結的一張圖片如下,此圖是使用XMind畫的,原件:https://files.cnblogs.com/files/wind-snow/Web路徑總結.zip