更新時間:2017-12-28 來源:黑馬程序員 瀏覽量:
在寫程序時,想要獲取某個資源文件,或想訪問某個Servlet,如果路徑寫不對,就找不到該文件,或訪問失敗。由此可見,路徑很重要。下面我們就來一一分析如何正確找到資源文件及訪問Servlet。
1.Servlet訪問路徑
Servlet的訪問路徑是在web.xml文件中配置的,如下所示:
Servlet訪問路徑
Servlet訪問路徑有如下兩種書寫方式:
l 路徑以“/”開頭
l 路徑以“*“開頭
Servlet的訪問路徑要么以“/”開頭,要么以“*”開頭,但是在Servlet中,現在很少使用“*”開頭,在后面將要學習的過濾器中會使用它來匹配要過濾的資源。
2.請求轉發和請求包含路徑
請求轉發和請求包含需要給出即將轉發和包含資源的路徑,例如:
request.getRequestDispatcher(“/BServlet”).forward(request,response),表示要轉發到BServlet。request對象的getRequestDispatcher(String path)方法的參數有如下兩種書寫方式:
l 以“/”開頭:
相對當前項目路徑,即:http://localhost:8080/項目名,例如:request.getRequestDispatcher(“/BServlet”)表示轉發或包含路徑為http://localhost:8080/項目名/BServlet的Servlet。
l 不以“/”開頭:
相對當前Servlet的路徑,例如:當前Servlet是AServlet,訪問它的路徑為http://localhost:8080/項目名/servlet/AServlet,那么request.getRequestDispatcher(“BServlet”)就相當于,轉發或包含路徑為http://localhost:8080/項目名/servlet/BServlet的Servlet。
以上兩種書寫方式中,以“/”開頭的路徑是絕對路徑,不以“/”開頭的路徑是相對路徑。為了以后的開發簡便,建議大家采用第一種方式,即以“/”開頭的路徑。
3.重定向路徑
進行重定向時,需要給出將要重定向的資源的路徑,例如:
response.sendRedirect(“/Example/BServlet”),表示重定向到Example項目中的訪問路徑為“/BServlet”的Servlet。
重定向中的路徑是客戶端路徑,只要是客戶端路徑都需要加上項目名,否則找不到將要訪問的資源。重定向路徑有以下要求:
l 路徑要以“/”開頭
以“/”開頭,相對當前主機,即http://localhost:8080,所以路徑上要加上項目名,如:response.sendRedirect(“/Example/Servlet”),對應的路徑就是:http://localhost:8080/Example/Servlet。
4.頁面中超鏈接和表單路徑
頁面中的超鏈接和表單路徑和重定向路徑一樣,也是客戶端路徑,因此路徑中要加上項目名。例如:
?
?
如果超鏈接或者表單路徑中沒有加上項目名,如:,并且沒有以“/”開頭,那么就是相對路徑,相對于當前頁面所在路徑。例如,超鏈接所在頁面是index.jsp,那么index.jsp頁面的路徑就是:http://localhost:8080/項目名,超鏈接路徑就是:http://localhost:8080/項目名/AServlet。如果是這樣就不存在問題,但是如果頁面并不是在應用的根目錄下,而是根目錄下的一個目錄中,例如html目錄中,那么index.jsp的訪問路徑就應該是:http://localhost:8080/項目名/html,那么再使用中的路徑就會出現問題,所以建議大家使用絕對路徑。
5.ServletContext獲取資源路徑
ServletContext獲取資源路徑使用的方式是getRealPath(String path),該方法獲取的是應用發布到Tomcat安裝目錄下的webapps目錄中的根目錄,如:servletContext.getRealPath(“/”)返回的路徑就是D:\apache-tomcat-7.0.42\webapps\項目名。具體內容請參考ServletContext讀取web應用中的資源文件。
6.ClassLoader獲取資源路徑
在之前的文檔中,我們講解了在Servlet中使用ClassLoader來獲取資源路徑,今天我們要學習的是在普通類中使用ClassLoader獲取資源路徑。具體如下:
(1)創建一個web應用,Example14,在該應用下的【src】目錄下新建txt文件,one.txt,文件內容如下所示:
hello one
(2)在該應用下新建一個Class類,DemoLoader,主要代碼如例1-1所示:
例1-1 DemoLoader.java
public class DemoLoader {
@Test
public void fun1() throws IOException{
//1.獲得ClassLoader對象
ClassLoader cl=this.getClass().getClassLoader();
InputStream in=cl.getResourceAsStream("one.txt");
String value= IOUtils.toString(in);
System.out.println(value);
}
}
在DemoLoader中,我們使用了IOUtils幫助類,該類是commons-io-1.4.jar包中的類,點擊此處
下載jar包。IOUtils類的toString(InputStream)方法是將輸入流轉換成字符串并返回。
(3)例1-1中,我們使用了單元測試,現在運行fun1()方法,運行結果如圖1-1所示:
圖1-1 運行結果
由運行結果可知,使用ClassLoader的getResourceAsStream(“one.txt”)方法獲取到了src目錄下的one.txt文件資源。
(4)現在將fun1()方法稍作修改,如例1-2所示:
例1-2 fun1()方法
@Test
public void fun1() throws IOException{
//1.獲得ClassLoader對象
ClassLoader cl=this.getClass().getClassLoader();
InputStream in=cl.getResourceAsStream("/one.txt");
String value= IOUtils.toString(in);
System.out.println(value);
}
例1-2相對于例1-1,在路徑上多加了“/“。
(5)再次運行fun1()方法,運行結果如圖1-2所示:
圖1-2 運行結果
由運行結果可知,路徑以“/”開頭,one.txt文件就找不到了。cl.getResource(“/”)獲取的URL為null,如果是cl.getResource(“”),那么獲取的URL的值為“file:/F:/space/Example13/WebRoot/WEB-INF/classes/“,因此要注意:
2 使用ClassLoader獲取資源路徑,資源路徑不能以“/“開頭。
7.Class獲取資源路徑
在之前的文檔中,我們也講解過在Servlet中使用Class來獲取資源路徑,下面我們要學習的是在普通類中使用Class獲取資源路徑,具體如下:
(1)在DemoLoader類中再次新建一個單元測試方法fun2(),主要代碼如例1-3所示:
例1-3 fun2()方法
@Test
public void fun2() throws IOException{
Class c=this.getClass();//獲取Clas對象
InputStream in=c.getResourceAsStream("/one.txt");//獲取one.txt文件流
System.out.println(IOUtils.toString(in));//打印文件內容
}
fun2()方法中,使用Class獲取資源時,資源路徑是以“/“開頭。
(2)運行fun2()方法,運行結果如圖1-3所示:
圖1-3 運行結果
(3)對fun2()方法稍作修改,如例1-4所示:
例1-4 fun2()方法
@Test
public void fun2() throws IOException{
Class c=this.getClass();//獲取Clas對象
InputStream in=c.getResourceAsStream("one.txt");//獲取one.txt文件流
System.out.println(IOUtils.toString(in));//打印文件內容
}
將例1-3中fun2()方法中的資源路徑前面的“/“去掉。
(4)再次運行fun2()方法,運行結果如圖1-4所示:
圖1-4 運行結果
圖1-4中,運行結果出現空指針異常,原因是沒有找到one.txt文件。
Myeclipse中的應用在工作空間中,目錄結構如圖1-5所示:
圖1-5 class文件所在目錄
one.txt文件在工作空間的位置,如圖1-6所示:
圖1-6 txt文件所在目錄
使用Class獲取資源路徑,要注意以下兩點:
l 路徑以“/“開頭:相對的是classes目錄,即在圖1-6中的目錄下查找文件;
例如:class.getResource(“/“),它返回的URL為:
file:/F:/space/Example14/WebRoot/WEB-INF/classes/
所以想要獲取src根目錄下的one.txt文件,可以通過class.getResourceAsStream(“/one.txt”)方法。
l 路徑不以“/”開頭:相對的是當前類的class文件所在的路徑,即在圖1-5中的目錄下查找文件;
例如:class.getResource(“”)方法的返回值為:
file:/F:/space/Example14/WebRoot/WEB-INF/classes/cn/itcast/road/
而通過class.getResource(“one.txt”)方法獲取one.txt文件,是在classes目錄下的cn/itcast/road目錄下查找one.txt,由于one.txt文件是在classes目錄下,所以報了圖1-4的空指針異常。
本文版權歸黑馬程序員JavaEE學院所有,歡迎轉載,轉載請注明作者出處。謝謝!
作者:黑馬程序員JavaEE培訓學院