Java中获取资源文件三种方式

2,953 阅读4分钟

获取资源文件有三种方式

  • 采用 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_HOMECATALINA_BASE的区别: 简单的说,CATALINA_HOME是Tomcat的安装目录,CATALINA_BASE是Tomcat的工作目录。 如果想要运行Tomcat的多个实例,但是不想安装多个Tomcat软件副本。那么可以配置多个工作目录,每个运行实例独占一个工作目录,但是共享同一个安装目录。 详细介绍可以参考我之前写的Tomcat文章,里面介绍了应用程序的部署方式:blog.csdn.net/CSDN_GIA/ar…

发布到服务器的路径.png

image.png
所以,b.properties文件位于服务器的根目录下,写法为/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

    /**
     * 获取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文件加载到虚拟机里运行,就用类加载器来加载,类加载器的主要目的就是将字节码文件加载到内存里,然后运行字节码文件

获取类加载器的方式

  1. 通过类名 : 类名.class.getClassLoader()

  2. 通过对象: this.getClass().getClassLoader()

  3. 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);
    }
}