更新時(shí)間:2017-12-28 來(lái)源:黑馬程序員 瀏覽量:
在寫程序時(shí),想要獲取某個(gè)資源文件,或想訪問(wèn)某個(gè)Servlet,如果路徑寫不對(duì),就找不到該文件,或訪問(wèn)失敗。由此可見,路徑很重要。下面我們就來(lái)一一分析如何正確找到資源文件及訪問(wèn)Servlet。
1.Servlet訪問(wèn)路徑
Servlet的訪問(wèn)路徑是在web.xml文件中配置的,如下所示:
Servlet訪問(wèn)路徑
Servlet訪問(wèn)路徑有如下兩種書寫方式:
l 路徑以“/”開頭
l 路徑以“*“開頭
Servlet的訪問(wèn)路徑要么以“/”開頭,要么以“*”開頭,但是在Servlet中,現(xiàn)在很少使用“*”開頭,在后面將要學(xué)習(xí)的過(guò)濾器中會(huì)使用它來(lái)匹配要過(guò)濾的資源。
2.請(qǐng)求轉(zhuǎn)發(fā)和請(qǐng)求包含路徑
請(qǐng)求轉(zhuǎn)發(fā)和請(qǐng)求包含需要給出即將轉(zhuǎn)發(fā)和包含資源的路徑,例如:
request.getRequestDispatcher(“/BServlet”).forward(request,response),表示要轉(zhuǎn)發(fā)到BServlet。request對(duì)象的getRequestDispatcher(String path)方法的參數(shù)有如下兩種書寫方式:
l 以“/”開頭:
相對(duì)當(dāng)前項(xiàng)目路徑,即:http://localhost:8080/項(xiàng)目名,例如:request.getRequestDispatcher(“/BServlet”)表示轉(zhuǎn)發(fā)或包含路徑為http://localhost:8080/項(xiàng)目名/BServlet的Servlet。
l 不以“/”開頭:
相對(duì)當(dāng)前Servlet的路徑,例如:當(dāng)前Servlet是AServlet,訪問(wèn)它的路徑為http://localhost:8080/項(xiàng)目名/servlet/AServlet,那么request.getRequestDispatcher(“BServlet”)就相當(dāng)于,轉(zhuǎn)發(fā)或包含路徑為http://localhost:8080/項(xiàng)目名/servlet/BServlet的Servlet。
以上兩種書寫方式中,以“/”開頭的路徑是絕對(duì)路徑,不以“/”開頭的路徑是相對(duì)路徑。為了以后的開發(fā)簡(jiǎn)便,建議大家采用第一種方式,即以“/”開頭的路徑。
3.重定向路徑
進(jìn)行重定向時(shí),需要給出將要重定向的資源的路徑,例如:
response.sendRedirect(“/Example/BServlet”),表示重定向到Example項(xiàng)目中的訪問(wèn)路徑為“/BServlet”的Servlet。
重定向中的路徑是客戶端路徑,只要是客戶端路徑都需要加上項(xiàng)目名,否則找不到將要訪問(wèn)的資源。重定向路徑有以下要求:
l 路徑要以“/”開頭
以“/”開頭,相對(duì)當(dāng)前主機(jī),即http://localhost:8080,所以路徑上要加上項(xiàng)目名,如:response.sendRedirect(“/Example/Servlet”),對(duì)應(yīng)的路徑就是:http://localhost:8080/Example/Servlet。
4.頁(yè)面中超鏈接和表單路徑
頁(yè)面中的超鏈接和表單路徑和重定向路徑一樣,也是客戶端路徑,因此路徑中要加上項(xiàng)目名。例如:
?
?
如果超鏈接或者表單路徑中沒有加上項(xiàng)目名,如:,并且沒有以“/”開頭,那么就是相對(duì)路徑,相對(duì)于當(dāng)前頁(yè)面所在路徑。例如,超鏈接所在頁(yè)面是index.jsp,那么index.jsp頁(yè)面的路徑就是:http://localhost:8080/項(xiàng)目名,超鏈接路徑就是:http://localhost:8080/項(xiàng)目名/AServlet。如果是這樣就不存在問(wèn)題,但是如果頁(yè)面并不是在應(yīng)用的根目錄下,而是根目錄下的一個(gè)目錄中,例如html目錄中,那么index.jsp的訪問(wèn)路徑就應(yīng)該是:http://localhost:8080/項(xiàng)目名/html,那么再使用中的路徑就會(huì)出現(xiàn)問(wèn)題,所以建議大家使用絕對(duì)路徑。
5.ServletContext獲取資源路徑
ServletContext獲取資源路徑使用的方式是getRealPath(String path),該方法獲取的是應(yīng)用發(fā)布到Tomcat安裝目錄下的webapps目錄中的根目錄,如:servletContext.getRealPath(“/”)返回的路徑就是D:\apache-tomcat-7.0.42\webapps\項(xiàng)目名。具體內(nèi)容請(qǐng)參考ServletContext讀取web應(yīng)用中的資源文件。
6.ClassLoader獲取資源路徑
在之前的文檔中,我們講解了在Servlet中使用ClassLoader來(lái)獲取資源路徑,今天我們要學(xué)習(xí)的是在普通類中使用ClassLoader獲取資源路徑。具體如下:
(1)創(chuàng)建一個(gè)web應(yīng)用,Example14,在該應(yīng)用下的【src】目錄下新建txt文件,one.txt,文件內(nèi)容如下所示:
hello one
(2)在該應(yīng)用下新建一個(gè)Class類,DemoLoader,主要代碼如例1-1所示:
例1-1 DemoLoader.java
public class DemoLoader {
@Test
public void fun1() throws IOException{
//1.獲得ClassLoader對(duì)象
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中,我們使用了單元測(cè)試,現(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對(duì)象
ClassLoader cl=this.getClass().getClassLoader();
InputStream in=cl.getResourceAsStream("/one.txt");
String value= IOUtils.toString(in);
System.out.println(value);
}
例1-2相對(duì)于例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獲取資源路徑
在之前的文檔中,我們也講解過(guò)在Servlet中使用Class來(lái)獲取資源路徑,下面我們要學(xué)習(xí)的是在普通類中使用Class獲取資源路徑,具體如下:
(1)在DemoLoader類中再次新建一個(gè)單元測(cè)試方法fun2(),主要代碼如例1-3所示:
例1-3 fun2()方法
@Test
public void fun2() throws IOException{
Class c=this.getClass();//獲取Clas對(duì)象
InputStream in=c.getResourceAsStream("/one.txt");//獲取one.txt文件流
System.out.println(IOUtils.toString(in));//打印文件內(nèi)容
}
fun2()方法中,使用Class獲取資源時(shí),資源路徑是以“/“開頭。
(2)運(yùn)行fun2()方法,運(yùn)行結(jié)果如圖1-3所示:
圖1-3 運(yùn)行結(jié)果
(3)對(duì)fun2()方法稍作修改,如例1-4所示:
例1-4 fun2()方法
@Test
public void fun2() throws IOException{
Class c=this.getClass();//獲取Clas對(duì)象
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 路徑以“/“開頭:相對(duì)的是classes目錄,即在圖1-6中的目錄下查找文件;
例如:class.getResource(“/“),它返回的URL為:
file:/F:/space/Example14/WebRoot/WEB-INF/classes/
所以想要獲取src根目錄下的one.txt文件,可以通過(guò)class.getResourceAsStream(“/one.txt”)方法。
l 路徑不以“/”開頭:相對(duì)的是當(dāng)前類的class文件所在的路徑,即在圖1-5中的目錄下查找文件;
例如:class.getResource(“”)方法的返回值為:
file:/F:/space/Example14/WebRoot/WEB-INF/classes/cn/itcast/road/
而通過(guò)class.getResource(“one.txt”)方法獲取one.txt文件,是在classes目錄下的cn/itcast/road目錄下查找one.txt,由于one.txt文件是在classes目錄下,所以報(bào)了圖1-4的空指針異常。
本文版權(quán)歸黑馬程序員JavaEE學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明作者出處。謝謝!
作者:黑馬程序員JavaEE培訓(xùn)學(xué)院
首發(fā):http://java.itheima.com/
JavaEE技術(shù)知識(shí)點(diǎn):Myeclipse Web開發(fā)
2017-12-26JavaEE技術(shù)知識(shí)點(diǎn):Myeclipse Web開發(fā)
2017-12-26JavaEE知識(shí)點(diǎn):MVC設(shè)計(jì)模式
2017-12-26JavaEE技術(shù)點(diǎn):MySQL目錄及基本命令介紹
2017-12-26JavaEE技術(shù)點(diǎn):MySQL編碼問(wèn)題
2017-12-26Java基礎(chǔ)教程:多線程(5)-----線程的調(diào)度之優(yōu)先級(jí)
2017-11-14