获取资源文件有三种方式
采用 ServletContext对象获取
采用ResourceBundle类来获取
采用类加载器获取
分别获取图中的a、b、c.properties:
image.png
文件内容分别是:a=a;b=b;c=c
重点:注意获取图中文件的路径写法,不是直接看ide中的位置,而是要看项目发布到tomcat之后该文件所在的位置。
一、采用 ServletContext对象获取
优点:任意文件,任意路径 缺点:必须有web环境
获取文件真实(服务器)路径:String getRealPath()
1.1 获取web目录下资源b.properties
写法:/b.properties
package com.hcx.web.servlet;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.FileReader;import java.io.IOException;import java.util.Properties;/** * Created by hongcaixia on 2019/11/19. */@WebServlet("/getResourceFileServlet")public class GetResourceFileServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { getWebResource(); } /** * 获取web下的资源b.properties,查看文件发布到tomcat的位置为/b.properties */ public void getWebResource(){ ServletContext servletContext = this.getServletContext(); String realPath = servletContext.getRealPath("/b.properties"); //文件的路径是:D:\WorkSpaces\IDEAWS\tomcatdemo\out\artifacts\tomcatdemo_war_exploded\b.properties System.out.println("文件的路径是:"+realPath); Properties properties = new Properties(); try { properties.load(new FileReader(realPath)); } catch (IOException e) { e.printStackTrace(); } Object b = properties.get("b"); //获取到的key是:b System.out.println("获取到的key值是:"+b); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); }}
项目启动后从日志中找到CATALINA_BASE值:C:\Users\HCX\.IntelliJIdea2017.2\system\tomcat\Tomcat_8_5_0_tomcatdemo
CATALINA_BASE.png
CATALINA_HOME
和CATALINA_BASE
的区别: 简单的说,CATALINA_HOME
是Tomcat的安装目录,CATALINA_BASE
是Tomcat的工作目录。 如果想要运行Tomcat的多个实例,但是不想安装多个Tomcat软件副本。那么可以配置多个工作目录,每个运行实例独占一个工作目录,但是共享同一个安装目录。 详细介绍可以参考我之前写的Tomcat文章,里面介绍了应用程序的部署方式:https://blog.csdn.net/CSDN_GIA/article/details/53423271
发布到服务器的路径.png
image.png
所以,b.properties文件位于服务器的根目录下,写法为
1.2 获取WEB-INF目录下资源c.properties
image.png
从上一个例子可以看出,/代表的服务器的路径是:D:\WorkSpaces\IDEAWS\tomcatdemo\out\artifacts\tomcatdemo_war_exploded
image.png
所以 WEB-INF下资源写法为:
/** * 获取WEB-INF下资源c.properties */ public void getWebINFOResource() { ServletContext servletContext = this.getServletContext(); String realPath = servletContext.getRealPath("/WEB-INF/c.properties"); //文件的路径是:D:\WorkSpaces\IDEAWS\tomcatdemo\out\artifacts\tomcatdemo_war_exploded\WEB-INF\c.properties System.out.println("文件的路径是:" + realPath); Properties properties = new Properties(); try { properties.load(new FileReader(realPath)); } catch (IOException e) { e.printStackTrace(); } Object c = properties.get("c"); //获取到的key值是:c System.out.println("获取到的key值是:" + c); }
1.3 获取src目录下资源a.properties
image.png
src下的所有资源将来会被放到WEB-INF目录下的classes目录下 写法:/WEB-INF/classes/a.properties
public void getSrcResource() { ServletContext servletContext = this.getServletContext(); String realPath = servletContext.getRealPath("/WEB-INF/classes/a.properties"); //文件的路径是:D:\WorkSpaces\IDEAWS\tomcatdemo\out\artifacts\tomcatdemo_war_exploded\WEB-INF\classes\a.properties System.out.println("文件的路径是:" + realPath); Properties properties = new Properties(); try { properties.load(new FileReader(realPath)); } catch (IOException e) { e.printStackTrace(); } Object a = properties.get("a"); //获取到的key值是:a System.out.println("获取到的key值是:" + a); }
二、采用ResourceBundle类来获取
优点:简单方便 缺点:
只能拿取properties文件
只能拿取非web环境下的资源(即src目录下的)
ResourceBundle类:该类(抽象类)专门用来加载资源,还可以处理一些国际化的东西
2.1 获取src目录下资源a.properties
image.png
public void getSrcResource() { //获取ResourceBundle对象(专门用来获取properties文件的信息,所以不用加后缀名.properties) ResourceBundle resourceBundle = ResourceBundle.getBundle("a"); String a = resourceBundle.getString("a"); System.out.println("src下资源文件:" + a); //获取ResourceBundle对象(专门用来获取properties文件的信息,所以不用加后缀名.properties) ResourceBundle resourceBundle2 = ResourceBundle.getBundle("com.hcx.web.d"); String d = resourceBundle2.getString("d"); System.out.println("src下资源文件:" + d); }
三、采用类加载器获取
优点:任意文件,任意路径 缺点:编写稍显麻烦
类加载器: 一个java文件,编写好之后是源码,后缀名是.java,要将这个源码首先采用编译命令javac把其编译为.class文件,该.class文件位于硬盘上,在运行时,需要把.class文件加载到虚拟机里运行,就用类加载器来加载,类加载器的主要目的就是将字节码文件加载到内存里,然后运行字节码文件
获取类加载器的方式
通过类名 :
类名.class.getClassLoader()
通过对象:
this.getClass().getClassLoader()
Class.forName():
Class.forName("类名").getClassLoader()
注意: this.getClass().getClassLoader().getResource("/");
是去类路径去加载资源,即classes目录下:
classes目录.png
3.1 获取web目录下资源b.properties
public void getWebResourceByClassLoader(){ //url:file:/D:/WorkSpaces/IDEAWS/tomcatdemo/out/artifacts/tomcatdemo_war_exploded/WEB-INF/classes/ URL url = this.getClass().getClassLoader().getResource("/"); InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("../../b.properties"); Properties properties = new Properties(); try { properties.load(resourceAsStream); } catch (IOException e) { e.printStackTrace(); } String b = properties.getProperty("b"); System.out.println(b); }
3.2 获取WEB-INF目录下资源c.properties
public void getWebInfoResourceByClassLoader(){ //url:file:/D:/WorkSpaces/IDEAWS/tomcatdemo/out/artifacts/tomcatdemo_war_exploded/WEB-INF/classes/ URL url = this.getClass().getClassLoader().getResource("/"); InputStream resourceAsStream1 = this.getClass().getClassLoader().getResourceAsStream("../../WEB-INF/c.properties"); Properties properties = new Properties(); try { properties.load(resourceAsStream1); } catch (IOException e) { e.printStackTrace(); } String c = properties.getProperty("c"); System.out.println(c); }
3.3 获取src目录下资源a.properties
package com.hcx.web.servlet;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.FileReader;import java.io.IOException;import java.io.InputStream;import java.util.Properties;import java.util.ResourceBundle;/** * Created by hongcaixia on 2019/11/19. */@WebServlet("/getResourceFileServlet")public class GetResourceFileServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { getSrcResourceByClassLoader(); } public void getSrcResourceByClassLoader(){ //获取类加载器方式: /** * 1.通过类名:ClassLoader classLoader = GetResourceFileServlet.class.getClassLoader(); * 2.通过对象:ClassLoader classLoader = this.getClass().getClassLoader(); * 3.通过Class.forName():ClassLoader classLoader = Class.forName("GetResourceFileServlet").getClassLoader(); */ InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("a.properties"); Properties properties = new Properties(); try { properties.load(resourceAsStream); } catch (IOException e) { e.printStackTrace(); } String a = properties.getProperty("a"); System.out.println(a); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); }}
十年IT老兵,专注后端技术