Java資源獲取
在Java獲取資源的時候恳啥,通過絕對路徑獲取資源的方法在部署到生產(chǎn)環(huán)境時就不可用了右冻,所以需要通過動態(tài)獲取文件路徑的方法或者是相對路徑的方法來獲取資源代咸。在學(xué)習(xí)JavaWeb開發(fā)時驹碍,對于獲取文件有很多的不同背犯,在這總結(jié)一下
-
Java程序中,通常通過
getResource()
方法獲取資源绍妨,其中有一下方法及其區(qū)別Class.getResource(String path); /* path不以"/"開頭時润脸,默認(rèn)是此包下獲取資源 path在以"/"開頭時,默認(rèn)是此項目的ClassPath根下獲取資源 */ package com.test.testResource; public class Main { public static void main(String[] args) { System.out.println(Main.class.getResource("/")); } } /* 輸出為file:/C:/Users/Chywan/OneDrive/daily_program/Java/LearningCode/Test/target/classes/ */ package com.test.testResource; public class Main { public static void main(String[] args) { System.out.println(Main.class.getResource("")); } } /* 輸出為file:/C:/Users/Chywan/OneDrive/daily_program/Java/LearningCode/Test/target/classes/com/test/testResource/ */ //所以他去,其實在沒有加入"/“時獲取的是相對于類的相對路徑為”“所對應(yīng)的絕對路徑毙驯,在使用”/“后獲取的是編譯后的類的路徑,如maven編譯的項目就是target/classes/ Class.getClassloader.getResource(); /* ClassLoader的加載是雙親委派機制灾测,所以在獲取Main.class.getClassLoader()時獲得的是BootstrapClassLoader,是C++底層實現(xiàn)的爆价,所以getResource("/")獲取的是null,而getResource("")時,獲取的是加載器的相對路徑媳搪,我的理解是加載器是從項目的類根路徑起效的铭段,所以就算類根路徑 */ package com.test.testResource; public class Main { public static void main(String[] args) { System.out.println(Main.class.getClassLoader().getResource("/")); } } /*輸出為null */ package com.test.testResource; public class Main { public static void main(String[] args) { System.out.println(Main.class.getClassLoader().getResource("")); } } /*輸出為file:/C:/Users/Chywan/OneDrive/daily_program/Java/LearningCode/Test/target/classes/ */ // 源碼里面可以看到resolveName()方法對路徑進行處理,本質(zhì)Class.getResource(String path)還是調(diào)用了ClassLoader的方法蛾号。 public URL getResource(String name) { name = resolveName(name); //獲取資源 } private String resolveName(String name) { if (!name.startsWith("/")) { //相對路徑 Class<?> c = this; while (c.isArray()) { c = c.getComponentType(); } String baseName = c.getPackageName(); //獲取包名 if (baseName != null && !baseName.isEmpty()) { //拼接路徑 name = baseName.replace('.', '/') + "/" + name; } } else { //根路徑開始 name = name.substring(1); } return name; }
-
JavaWeb中稠项,通常使用
getContextPath()
涯雅、getServletPath()
鲜结、getRequestURI()
、request.getRealPath()
等獲取資源活逆,區(qū)別如下protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println(getServletContext().getRealPath("/")); System.out.println(getServletContext().getContextPath()); System.out.println(req.getContextPath()); System.out.println(req.getServletPath()); System.out.println(req.getRealPath("/")); System.out.println(req.getRequestURI()); }
輸出為
C:\Users\Chywan\env\apache-tomcat-9.0.37\webapps\Test_war\
/Test_war
/Test_war
/test
C:\Users\Chywan\env\apache-tomcat-9.0.37\webapps\Test_war\
/Test_war/test
分析可知:
getRealPath()
獲取的是文件在存儲的絕對路徑
getRequestURI()
獲取的是項目名到請求的地址的路徑
getContextPath()
獲取的是項目名精刷,也就是在Tomcat定位項目的名字,也叫做項目上下文context
getServletPath()
獲取的是請求名蔗候,也可以說是Servlet的位置怒允,請求名是因為在web.xml中做了映射,如果是jsp獲取就是jsp的路徑