獲取資源的主要有3種,分別是ServletContext
、Class
和ClassLoader
。其中,
ServletContext
是WEB階段的,Tomcat提供的一種獲取資源的方式;
Class
和ClassLoader
獲取資源主要是JDK提供的一種獲取資源的方式。
1.ServletContext獲取資源
獲取ServletContext的方法如下:
1)使用request獲取: request.getSession().getServletContext();
2)在Servlet中獲取:this.getServletContext();
3)使用FilterConfig對象獲取(在Filter中使用):config.getServletContext();
ServletContext,不能通過絕對地址來讀取資源文件,文件路徑是相對於web項目
(如/javaee)根路徑而言的。參數中的路徑必須是相對路徑,可以“/”開頭,也可以不使用“/”開頭,但無論是否使用“/”開頭都是相對當前應用路徑,建議以"/"開頭。
(1) getResourceAsStream
public class ServletContextServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
InputStream in = this.getServletContext(). getResourceAsStream("/WEB-INF/classes/cn/ccnu/path/db.properties/a.properties");
InputStream in1 = this.getServletContext(). getResourceAsStream("WEB-INF/classes/cn/ccnu/path/db.properties/a.properties");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
(2) getRealPath
通過ServletContext的getRealPath方法獲取文件絕對路徑(win帶有盤符), 然後操作文件流。
public class ServletContextServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String path = this.getServletContext().getRealPath("/WEB-INF/classes/cn/ccnu/path/db.properties/a.properties");
String path1 = this.getServletContext().getRealPath("WEB-INF/classes/cn/ccnu/path/db.properties/a.properties");
String path2 = this.getServletContext().getRealPath(""); //當前web應用的路徑
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
2.ClassLoader獲取資源
ClassLoader不能通過絕對地址來加載資源,文件路徑是相對於類目錄
而言的(maven工程中一般爲/target/classes),參數中的路徑可以以“/”開頭,也可以不以“/”開頭,帶不帶“/”的都表示相對於當前類的路徑。
獲取classLoaderl兩種方式
1)xxx.class.getClassLoader()
2)this.getClass().getClassLoader()
(1) getResourceAsStream
public class ClassLoaderServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
InputStream in = this.getClass().getClassLoader().getResourceAsStream("/cn/ccnu/classloaderpath/c.properties");
InputStream in1 = this.getClass().getClassLoader().getResourceAsStream("cn/ccnu/classloaderpath/c.properties");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
(2) getResource方式
public class ClassLoaderServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String path =this.getClass().getClassLoader().
getResource("cn/ccnu/classloaderpath/c.properties").getPath();
String path1 =this.getClass().getClassLoader().
getResource("/cn/ccnu/classloaderpath/c.properties").getPath();
String path2 =this.getClass().getClassLoader().
getResource("").getPath(); //classes/的真實路徑(win帶有盤符)
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
3.Class獲取資源
Class.getResource和ClassLoader.getResource 最終調用的是ClassLoader 類的getResource方法。
Class讀取資源不能是絕對路徑,只能是相對路徑,又分爲以/開頭或者是不以/開頭
- 以/開頭的相對路徑 ,此時的/代表類路徑【類路徑,即:/javaee/WEB-INF/classes】
- 不以/開頭的相對路徑 , 此時寫的時候,相對的是當前資源文件所在的路徑。
eg:即(此處當前資源):/javaee/WEB-INF/classes/cn/ccnu/classpath
4. springboot打成jar包在linux線上服務器無法讀取resource下文件問題
Linux上面部署爲jar包,在Linux中無法直接訪問未經解壓的文件,只能通過流的方式讀取文件:
- 1)this.getClass().getClassLoader().getResourceAsStream("xxx")
- 2)class.getResourceAsStream("xxx")
- 3)ClassPathResource resource = new ClassPathResource("xxx");
InputStream fis = resource.getInputStream();
創建ClassPathResource對象時,我們可以指定是按Class的相對路徑獲取文件還是按ClassLoader來獲取。
參考
JavaWeb(七)之詳解JavaWeb路徑
徹底搞懂Class.getResource和ClassLoader.getResource的區別和底層原理