教育行業(yè)A股IPO第一股(股票代碼 003032)

全國(guó)咨詢(xún)/投訴熱線(xiàn):400-618-4000

JavaEE技術(shù)點(diǎn)之Java路徑問(wèn)題

更新時(shí)間:2017年12月28日17時(shí)26分 來(lái)源:傳智播客 瀏覽次數(shù):

在寫(xiě)程序時(shí),想要獲取某個(gè)資源文件,或想訪(fǎng)問(wèn)某個(gè)Servlet,如果路徑寫(xiě)不對(duì),就找不到該文件,或訪(fǎng)問(wèn)失敗。由此可見(jiàn),路徑很重要。下面我們就來(lái)一一分析如何正確找到資源文件及訪(fǎng)問(wèn)Servlet。

1.Servlet訪(fǎng)問(wèn)路徑

Servlet的訪(fǎng)問(wèn)路徑是在web.xml文件中配置的,如下所示:

Servlet訪(fǎng)問(wèn)路徑

Servlet訪(fǎng)問(wèn)路徑有如下兩種書(shū)寫(xiě)方式:

l 路徑以“/”開(kāi)頭

l 路徑以“*“開(kāi)頭

Servlet的訪(fǎng)問(wèn)路徑要么以“/”開(kāi)頭,要么以“*”開(kāi)頭,但是在Servlet中,現(xiàn)在很少使用“*”開(kāi)頭,在后面將要學(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ù)有如下兩種書(shū)寫(xiě)方式:

l 以“/”開(kāi)頭:

相對(duì)當(dāng)前項(xiàng)目路徑,即:http://localhost:8080/項(xiàng)目名,例如:request.getRequestDispatcher(“/BServlet”)表示轉(zhuǎn)發(fā)或包含路徑為http://localhost:8080/項(xiàng)目名/BServlet的Servlet。

l 不以“/”開(kāi)頭:

相對(duì)當(dāng)前Servlet的路徑,例如:當(dāng)前Servlet是AServlet,訪(fǎng)問(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。

以上兩種書(shū)寫(xiě)方式中,以“/”開(kāi)頭的路徑是絕對(duì)路徑,不以“/”開(kāi)頭的路徑是相對(duì)路徑。為了以后的開(kāi)發(fā)簡(jiǎn)便,建議大家采用第一種方式,即以“/”開(kāi)頭的路徑。

3.重定向路徑

進(jìn)行重定向時(shí),需要給出將要重定向的資源的路徑,例如:

response.sendRedirect(“/Example/BServlet”),表示重定向到Example項(xiàng)目中的訪(fǎng)問(wèn)路徑為“/BServlet”的Servlet。

重定向中的路徑是客戶(hù)端路徑,只要是客戶(hù)端路徑都需要加上項(xiàng)目名,否則找不到將要訪(fǎng)問(wèn)的資源。重定向路徑有以下要求:

l 路徑要以“/”開(kāi)頭

以“/”開(kāi)頭,相對(duì)當(dāng)前主機(jī),即http://localhost:8080,所以路徑上要加上項(xiàng)目名,如:response.sendRedirect(“/Example/Servlet”),對(duì)應(yīng)的路徑就是:http://localhost:8080/Example/Servlet。

4.頁(yè)面中超鏈接和表單路徑

頁(yè)面中的超鏈接和表單路徑和重定向路徑一樣,也是客戶(hù)端路徑,因此路徑中要加上項(xiàng)目名。例如:

Ø

Ø

如果超鏈接或者表單路徑中沒(méi)有加上項(xiàng)目名,如:,并且沒(méi)有以“/”開(kāi)頭,那么就是相對(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的訪(fǎng)問(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í)的是在普通類(lèi)中使用ClassLoader獲取資源路徑。具體如下:

(1)創(chuàng)建一個(gè)web應(yīng)用,Example14,在該應(yīng)用下的【src】目錄下新建txt文件,one.txt,文件內(nèi)容如下所示:

hello one

(2)在該應(yīng)用下新建一個(gè)Class類(lèi),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幫助類(lèi),該類(lèi)是commons-io-1.4.jar包中的類(lèi),點(diǎn)擊此處

下載jar包。IOUtils類(lèi)的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é)果可知,路徑以“/”開(kāi)頭,one.txt文件就找不到了。cl.getResource(“/”)獲取的URL為null,如果是cl.getResource(“”),那么獲取的URL的值為“file:/F:/space/Example13/WebRoot/WEB-INF/classes/“,因此要注意:

² 使用ClassLoader獲取資源路徑,資源路徑不能以“/“開(kāi)頭。

7.Class獲取資源路徑

在之前的文檔中,我們也講解過(guò)在Servlet中使用Class來(lái)獲取資源路徑,下面我們要學(xué)習(xí)的是在普通類(lèi)中使用Class獲取資源路徑,具體如下:

(1)在DemoLoader類(lèi)中再次新建一個(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í),資源路徑是以“/“開(kāi)頭。

(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)空指針異常,原因是沒(méi)有找到one.txt文件。

Myeclipse中的應(yīng)用在工作空間中,目錄結(jié)構(gòu)如圖1-5所示:

圖1-5 class文件所在目錄

one.txt文件在工作空間的位置,如圖1-6所示:

圖1-6 txt文件所在目錄

使用Class獲取資源路徑,要注意以下兩點(diǎn):

l 路徑以“/“開(kāi)頭:相對(duì)的是classes目錄,即在圖1-6中的目錄下查找文件;

例如:class.getResource(“/“),它返回的URL為:

file:/F:/space/Example14/WebRoot/WEB-INF/classes/

所以想要獲取src根目錄下的one.txt文件,可以通過(guò)class.getResourceAsStream(“/one.txt”)方法。

l 路徑不以“/”開(kāi)頭:相對(duì)的是當(dāng)前類(lèi)的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é)院
0 分享到:
和我們?cè)诰€(xiàn)交談!