获取资源的主要有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的区别和底层原理