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