Java Resource资源path载入解惑

一、问题引入

最近使用如下方式载入配置文件时总是返回null
Thread.currentThread().getContextClassLoader().getResource("config.properties")

配置文件说明:config.properties文件放置在与src目录同级的config目录中。

二、问题分析

查看API文档发现关于类ClassLoader方法getResource的返回值有如下描述:
读取资源的 URL 对象;如果找不到该资源,或者调用者没有足够的权限获取该资源,则返回 null。
由文档API可知,返回null有两种原因引起:

  1. 找不到该资源;
  2. 对该资源没有获取权限。

这里显然可以排除第2中原因,那么明明config/config.properties文件存在,为什么会找不到呢?

原因和Java Resource资源载入路径有关。

默认情况下,Java在载入资源时,只会在工程的classpath下寻找

这里需要说明的是对classpath的认识不要局限在只是在这里寻找二进制class文件、jar包,Java还会在这里寻找文本文件(例如配置文件),图像,声音资源等。

为了一探究竟,我们打印出classpath,可以通过如下两种方式:

  1. 获取属性java.class.path:

    System.getProperty("java.class.path")
  2. 利用如下代码段:

    ClassLoader classLoader = ClassLoader.getSystemClassLoader();
        //Get the URLs
        URL[] paths = ((URLClassLoader)sysClassLoader).getURLs();
        for(int i=0; i< paths.length; i++)
        {
            System.out.println(paths[i].getFile());
        }

以上两种方式,得到的classpath结果相同:

/Users/zq/Documents/workspace/yourProjectName/bin/
/Users/zq/Documents/workspace/yourProjectName/lib/ant.jar
/Users/zq/Documents/workspace/yourProjectName/lib/commons-logging-1.0.4.jar
/Users/zq/Documents/workspace/yourProjectName/lib/log4j-1.2.9.jar
/Users/zq/Documents/workspace/yourProjectName/lib/mysql-connector-java-5.1.33-bin.jar
/Users/zq/Documents/workspace/yourProjectName/lib/httpclient-4.3.1.jar
/Users/zq/Documents/workspace/yourProjectName/lib/httpcore-4.3.jar
/Users/zq/Documents/workspace/yourProjectName/lib/commons-codec-1.6.jar
/Users/zq/Documents/workspace/yourProjectName/lib/commons-lang-2.6.jar
/Users/zq/Documents/workspace/yourProjectName/lib/mail-1.4.5.jar
/Users/zq/Documents/workspace/yourProjectName/lib/trove-3.0.0a6.jar

其中可以看出classpath中并没有包含config/config.properties

三、问题解决

到目前为止,问题的原因已经搞清楚了,那么问题的解决也就迎刃而解了:
只要把config/config.properties添加到工程的build path中即可。
再次打印出classpath,可以看到最后一行已经包含了config目录:

······
/Users/zq/Documents/workspace/yourProjectName/lib/commons-lang-2.6.jar
/Users/zq/Documents/workspace/yourProjectName/lib/mail-1.4.5.jar
/Users/zq/Documents/workspace/yourProjectName/lib/trove-3.0.0a6.jar
/Users/zq/work_xxx/yourProjectName/config/

四、深入探究

在Java工程中,获取资源一般通过如下两种方式(相应的getResourceAsStream方法返回的是同一资源的流形式inputstream):

  1. Class.getResource()

  2. ClassLoader.getResource()

    ClassLoader的获取:
    1. Thread.currentThread().getContextClassLoader()
    2. clazz.getClassLoader()
    3. ClassLoader. getSystemClassLoader()

两者的区别为:第一种方式在相对clazz的路径中寻找资源;第二种方式是在整个classpath中寻找资源。
两者的共同点为:都在classpath中寻找资源。

最后需要说明的是:
Java中不存在标准的相对路径,各种相对路径取资源的方式都是基于某种规则转化为绝对路劲,但是在编程过程中,绝对不要直接使用绝对路径。

所以,我们在使用Java载入Resource资源时,只要寻找到合适的参考基点,就能很轻松得定位你要找的resource资源,一般情况下参考基点有如下几种:

  1. classpath:
    本博文已经详细的做了介绍,这里不再做赘述。
  2. 当前工程目录(强烈不推荐使用,会带来移植问题)

    System.getProperty("user.dir")
  3. Web应用程序的根目录
    在Web应用程序中,一般通过ServletContext.getRealPath("/" )方法得到Web应用程序的根目录的绝对路径。

五、参考链接:
http://blog.csdn.net/cutesource/article/details/6141768
http://blog.csdn.net/ak913/article/details/7399056

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值