首頁技術(shù)文章正文

JavaEE技術(shù)點之Java路徑問題

更新時間: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)前項目路徑,即:http://localhost:8080/項目名,例如:request.getRequestDispatcher(“/BServlet”)表示轉(zhuǎn)發(fā)或包含路徑為http://localhost:8080/項目名/BServlet的Servlet。

l 不以“/”開頭:

相對當(dāng)前Servlet的路徑,例如:當(dāng)前Servlet是AServlet,訪問它的路徑為http://localhost:8080/項目名/servlet/AServlet,那么request.getRequestDispatcher(“BServlet”)就相當(dāng)于,轉(zhuǎn)發(fā)或包含路徑為http://localhost:8080/項目名/servlet/BServlet的Servlet。

以上兩種書寫方式中,以“/”開頭的路徑是絕對路徑,不以“/”開頭的路徑是相對路徑。為了以后的開發(fā)簡便,建議大家采用第一種方式,即以“/”開頭的路徑。

3.重定向路徑

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

response.sendRedirect(“/Example/BServlet”),表示重定向到Example項目中的訪問路徑為“/BServlet”的Servlet。

重定向中的路徑是客戶端路徑,只要是客戶端路徑都需要加上項目名,否則找不到將要訪問的資源。重定向路徑有以下要求:

l 路徑要以“/”開頭

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

4.頁面中超鏈接和表單路徑

頁面中的超鏈接和表單路徑和重定向路徑一樣,也是客戶端路徑,因此路徑中要加上項目名。例如:

?

?

如果超鏈接或者表單路徑中沒有加上項目名,如:,并且沒有以“/”開頭,那么就是相對路徑,相對于當(dāng)前頁面所在路徑。例如,超鏈接所在頁面是index.jsp,那么index.jsp頁面的路徑就是:http://localhost:8080/項目名,超鏈接路徑就是:http://localhost:8080/項目名/AServlet。如果是這樣就不存在問題,但是如果頁面并不是在應(yīng)用的根目錄下,而是根目錄下的一個目錄中,例如html目錄中,那么index.jsp的訪問路徑就應(yīng)該是:http://localhost:8080/項目名/html,那么再使用中的路徑就會出現(xiàn)問題,所以建議大家使用絕對路徑。

5.ServletContext獲取資源路徑

ServletContext獲取資源路徑使用的方式是getRealPath(String path),該方法獲取的是應(yīng)用發(fā)布到Tomcat安裝目錄下的webapps目錄中的根目錄,如:servletContext.getRealPath(“/”)返回的路徑就是D:\apache-tomcat-7.0.42\webapps\項目名。具體內(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包中的類,點擊此處

下載jar包。IOUtils類的toString(InputStream)方法是將輸入流轉(zhuǎn)換成字符串并返回。

(3)例1-1中,我們使用了單元測試,現(xiàn)在運行fun1()方法,運行結(jié)果如圖1-1所示:

Java路徑

圖1-1 運行結(jié)果

由運行結(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)再次運行fun1()方法,運行結(jié)果如圖1-2所示:

Java路徑

圖1-2 運行結(jié)果

由運行結(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)運行fun2()方法,運行結(jié)果如圖1-3所示:

Java路徑

圖1-3 運行結(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)再次運行fun2()方法,運行結(jié)果如圖1-4所示:

Java路徑

圖1-4 運行結(jié)果

圖1-4中,運行結(jié)果出現(xiàn)空指針異常,原因是沒有找到one.txt文件。

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

Java路徑

圖1-5 class文件所在目錄

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

Java路徑

圖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 路徑不以“/”開頭:相對的是當(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/

分享到:
在線咨詢 我要報名
和我們在線交談!