溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

web資源如何利用ServletContext類進行獲取

發(fā)布時間:2020-11-27 16:28:00 來源:億速云 閱讀:307 作者:Leah 欄目:編程語言

web資源如何利用ServletContext類進行獲?。亢芏嘈率謱Υ瞬皇呛芮宄?,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

ServletContext類中有這么四個方法:

  1. getRealPath(String path)

  2. getResource(String path)

  3. getResourceAsStream(String path)

  4. getResourcePaths(String path)

這四個方法都使用web工程下某個web資源路徑的字符串表現(xiàn)形式作為參數(shù),而每個方法返回不同的類型,我們通過這四個方法之一可以獲取某個資源,并對其進行讀取和修改操作。

假設我們的【myservlet】web工程中有一個數(shù)據(jù)庫的配置文件:database.properties,在這個數(shù)據(jù)庫中已經(jīng)有了一些參數(shù),而我們在web工程中希望讀取這個配置文件中的有關信息:

web資源如何利用ServletContext類進行獲取

先來看看ServletContext中的getResourceAsStream()方法,這個方法返回InputStream對象。由于我們的配置文件為properties文件,所以可以用Properties對象來裝載這個輸入流,代碼如下:

 public void doGet(HttpServletRequest request, HttpServletResponse response)
       throws ServletException, IOException {
     ServletContext context = this.getServletContext();
     InputStream in = context.getResourceAsStream("/database.properties");
     
     Properties prop = new Properties();
     prop.load(in);
     
     String url = prop.getProperty("url");
     String username = prop.getProperty("username");
     String password = prop.getProperty("password");
     System.out.println(url);
     System.out.println(username);
     System.out.println(password);
   }

最后在瀏覽器中訪問這個Servlet,那么在MyEclipse的控制臺上能看到的數(shù)據(jù)正好是database.properties中我們配置的信息:

web資源如何利用ServletContext類進行獲取

接下來看看ServletContext中的getRealPath()方法,這個方法返回String對象。由于我們的配置文件為properties文件,所以可以用Properties對象來裝載這個輸入流,代碼如下:

   ServletContext context = this.getServletContext();
     String filePath = context.getRealPath("/database.properties");
     
     FileInputStream fis = new FileInputStream(filePath);
     Properties prop = new Properties();
     prop.load(fis);
     
     String url = prop.getProperty("url");
     String username = prop.getProperty("username");
     String password = prop.getProperty("password");
     System.out.println(url);
     System.out.println(username);
     System.out.println(password);

最后在瀏覽器中訪問這個Servlet,那么在MyEclipse的控制臺上能看到的數(shù)據(jù)正好是database.properties中我們配置的信息:

web資源如何利用ServletContext類進行獲取

使用getRealPath()方法的好處在于這個方法還可以獲取文件名,而getResourceAsStream()方法就只能獲取文件流了。例如獲取文件名:

    ServletContext context = this.getServletContext();
     String filePath = context.getRealPath("/WEB-INF/web.xml");
     System.out.println(filePath);
     
     if(filePath == null) {
       System.out.println("所找文件不存在!");
     }
     String fileName = filePath.substring(filePath.lastIndexOf("\\"));
     System.out.println("文件為:"+fileName);

接著來看看ServletContext中的getResource()方法,這個方法返回URL對象。而URL對象具有打開到此 URL 的連接并返回一個用于從該連接讀入的 InputStream的openStream()方法。由于我們的配置文件為properties文件,所以可以用Properties對象來裝載這個輸入流,代碼如下:

    ServletContext context = this.getServletContext();
     URL fileUrl = context.getResource("/database.properties");
     InputStream in = fileUrl.openStream();
     
     Properties prop = new Properties();
     prop.load(in);
     
     String url = prop.getProperty("url");
     String username = prop.getProperty("username");
     String password = prop.getProperty("password");
     System.out.println(url);
     System.out.println(username);
     System.out.println(password);

最后在瀏覽器中訪問這個Servlet,那么在MyEclipse的控制臺上能看到的數(shù)據(jù)正好是database.properties中我們配置的信息:

web資源如何利用ServletContext類進行獲取

以上說完了幾種通過ServletContext對象來讀取web應用下的某個資源文件,只要通過讀取的方法,并將資源相對于web工程的路徑作為參數(shù)傳入其中便可。我們上述的例子都是直接在web工程中,或者web工程的某個目錄下,而如果我們把某個web資源放置在MyEclipse中的【src】目錄中,那么該如何讀取呢:

web資源如何利用ServletContext類進行獲取

我們說過,這個web應用在發(fā)布時,會將【src】目錄下的.java文件編譯成為.class字節(jié)碼文件,由服務器自動將這些字節(jié)碼文件放置在該web應用中的【W(wǎng)EB-INF】下的【classes】目錄里,如果沒有【classes】目錄,服務器會自動幫我們創(chuàng)建,因此,只要是放置在【src】目錄中的資源,最后也會被服務器自動放置在【classes】目錄中,這樣我們可以繼續(xù)通過ServletContext對象來獲?。?/p>

    ServletContext context = this.getServletContext();
     InputStream in = context.getResourceAsStream("/WEB-INF/classes/database.properties");
     
     Properties prop = new Properties();
     prop.load(in);
     
     String url = prop.getProperty("url");
     String username = prop.getProperty("username");
     String password = prop.getProperty("password");
     System.out.println(url);
     System.out.println(username);
     System.out.println(password);

web資源如何利用ServletContext類進行獲取

關于web工程下某個web資源在不同位置下的問題:

問題一:我們?yōu)槭裁床荒苡脗鹘y(tǒng)方式,如FileInputStream或者File對象來直接獲取web工程中的資源呢?其實也是可以的,但是有個路徑的問題,Servlet中方法所需要的路徑都是相對于web應用的路徑,而傳統(tǒng)的FileInputStream等等中方法所需的路徑參數(shù)都是相對于虛擬機的路徑。而又因為我這個web應用是從MyEclipse中的Tomcat里啟動的,所以這時候的虛擬機目錄其實是Tomcat中的【bin】目錄。所以如果想用傳統(tǒng)方式讀取文件必須每次都將文件放置在Tomcat的【bin】目錄下, 這是多么麻煩的事,因此我們開發(fā)web工程就應該使用web工程中的方法來讀取文件!但是,這卻又引出了問題二。。。

問題二:當我們web工程中有別的非Servlet的類時,比如JavaBean,當JavaBean需要連接數(shù)據(jù)庫時,這就是非Servlet對象讀取web工程中的資源文件了,不能用ServletContext來讀取,問題一種也說過不能用傳統(tǒng)方式如FileInputStream來讀取,那么該如何讀取呢?

答案是:類加載器!由于在【src】目錄下的Java程序經(jīng)過編譯成字節(jié)碼class文件,如果要用到這些類,Java虛擬機需要先將這些字節(jié)碼文件加載到內存中才可以使用,而這個過程就是由類加載器來完成。因此這就有一個知識點,如果我們將某個web資源放置在【src】目錄下,因為這是個web工程,服務器會自動將各個字節(jié)碼文件重新放置在【classes】目錄下, 而這個web資源也會重新被服務器放置在【classes】目錄下,那么類加載器能加載【classes】目錄下所有的字節(jié)碼文件,同時,同處在這個目錄下的web資源也會被類加載器加載進內存,這時我們就可以使用類加載器讀取該web資源了。

例:在【myservlet】的dao包中創(chuàng)建一個Student的JavaBean對象,并在src【目錄下】創(chuàng)建一個student的配置文件student.properties,而這個配置文件內容如下圖所示:

web資源如何利用ServletContext類進行獲取

在Student類中,我們需要通過類加載器來獲取輸入流來讀取這個文件:

 public class Student {  
   public void getStudent() throws IOException {
     ClassLoader loader = Student.class.getClassLoader();
     InputStream in = loader.getResourceAsStream("student.properties");
     
     Properties prop = new Properties();
     prop.load(in);
     
     String studentName = prop.getProperty("name");
     String studentAge = prop.getProperty("age");
     System.out.println(studentName+":"+studentAge);
   }
 }

另外創(chuàng)建一個Servlet作為可以供瀏覽器訪問的對象,在該Servlet中創(chuàng)建Student的示例來獲取配置文件中的內容,這樣就達到了從非Servlet對象讀取web資源內容并向Servlet對象傳遞數(shù)據(jù):

 public class ServletDemo extends HttpServlet {
   public void doGet(HttpServletRequest request, HttpServletResponse response)
       throws ServletException, IOException {
 
     Student student = new Student();
     student.getStudent();
   }
 }

從瀏覽器中訪問該Servlet,可以看到通過類加載器讀取的配置文件中的內容:

web資源如何利用ServletContext類進行獲取

注意,這種方法只能是web資源放置在【src】目錄中才可以使用,如果要讀取的web資源是放置在web工程的目錄下,使用類加載器也還是無法讀取,因為類加載器只能讀取類目錄下的文件,這時候非Servlet類就無法讀取資源文件,只能使用ServletContext來讀取了。

方立勛老師說:“類加載器只能加載【classes】目錄下的所有文件一次,這樣在服務器運行web工程的過程中,如果我們修改【classes】目錄下的student.properties配置文件,則由于類加載器不再加載,因此使用類加載器的方式不能讀取修改后的內容”

但是我修改后,還是可以使用類加載器的方式讀取classes】目錄下修改后的student.properties配置文件,難道是因為JDK7的原因嗎?

不過不管是什么原因,方立勛老師針對他的問題所采取的解決方案還是值得學習的,他采用先用類加載器獲取該配置文件的路徑,然后再采用傳統(tǒng)方式獲取這個文件的輸入流。所以在Student中的getStudent()方法代碼改為:

 public class Student {  
   public void getStudent() throws IOException {
     ClassLoader loader = Student.class.getClassLoader();
     URL fileUrl = loader.getResource("student.properties");
     String filePath = fileUrl.getPath();
 
     FileInputStream fis = new FileInputStream(filePath);
     Properties prop = new Properties();
     prop.load(fis);
     
     String studentName = prop.getProperty("name");
     String studentAge = prop.getProperty("age");
     System.out.println(studentName+":"+studentAge);  
 }
 }

這種方式還有一種好處就是,如果要讀取的文件過大,而之前通過類加載器將大文件加載進內存就容易導致內存溢出,所以還是采用這種方式比較好。

最后再說明一點,如果是在非Servlet類中采用類加載器獲取【classes】目錄中的資源,方法參數(shù)的路徑只需要是相對于【src】目錄即可。

補充:使用類加載器加載【classes】目錄中的資源,得到的路徑取決是哪個虛擬機(或服務器)調用,例如上面的代碼getStudent()方法,如果是在非Servlet的類的方法中被調用,那么就是使用JVM虛擬機,那么得到的資源路徑并不是Tomcat的應用【webapps】目錄的路徑。因此如果是要為Servlet中提供資源,那么非Servlet類中獲取資源的方法,請一定要使用Servlet來調用,這樣才能保證得到的資源路徑是在Tomcat服務器下的自己的web應用所在目錄中的正確位置。

例如下面的例子,我的MyEclipse工作空間在【E】盤,而Tomcat服務器所在路徑為【F】盤:

 public class ResourceUtils {
   
   public static void main(String[] args) throws IOException {
     getResource();
   }
   
   @Test
   public static void getResource() throws IOException {
     
     ClassLoader loader = ResourceUtils.class.getClassLoader();
     URL url = loader.getResource("student.properties");
     String path = url.getPath();
     System.out.println(path);
   }
 }

而資源為student.properties配置文件,放置的位置為【src】目錄下:

web資源如何利用ServletContext類進行獲取

這個是在我的一個web應用中定義的一個非Servlet的普通Java類,這個類無論是用JUnit測試還是使用Main函數(shù),亦或是使用別的非Servlet類來調用getResource方法獲取在web應用下【src】目錄中的student.properties資源,顯示的路徑為MyEclipse的工作空間,而不是Tomcat服務器:

web資源如何利用ServletContext類進行獲取

而如果是使用Servlet來調用的話,才是真正顯示在Tomcat中web應用所在的地方:

 public class ServletDemo extends HttpServlet {
 
   public void doGet(HttpServletRequest request, HttpServletResponse response)
       throws ServletException, IOException {
 
     ResourceUtils.getResource();
   }
 }

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業(yè)資訊頻道,感謝您對億速云的支持。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

AI