首页 > 代码库 > 读取配置文件的正确姿势(关于配置文件的路径获取)

读取配置文件的正确姿势(关于配置文件的路径获取)


0、写在前面的话

最近在做微信的公众号开发,因为调用微信接口失败的话是以各类错误码和错误信息返回的,在Github发现有位老哥整理成了xml(weixin/error.xml),索性也就想借鉴他的方式和这份xml,将内容读取存储到一个Map中,这样在遇到微信返回的错误码时就可以从Map中取出对应的具体错误信息。

在工具类中建立一个静态块,然后试图读取xml然后存入Map,问题来了,之前在Servlet中都是利用的ServletContext上下文对象,使用getRealPath(String path)方法获取文件路径。可是这个工具类并不是Servlet,也就没有ServletContext。

然而,什么都难不倒Google,下面就类似的配置文件的读取问题,进行一下总结。

另外,要说一个前提是,xml、properties等配置文件和Java资源都是放在WEB-INF下面的classes文件夹中(以下则称之为classpath)。我们的目的是如何获取该目录下的文件资源,假如我们现在的文件为应用根目录下" .../WEB-INF/classes/error.xml "。

技术分享
 

1、在Servlet类中读取

假如要将文件获取为流,有两种读取方式:

(1)直接读取文件为流,getResourceAsStream(path)方法,path默认为应用的根目录
  1. InputStream inputStream = this.getServletContext().getResourceAsStream("/WEB-INF/classes/error.xml");

(2)先读取文件,再读取为流,获取路径的方式和上面是类似的
  1. String path = this.getServletContext().getRealPath("/WEB-INF/classes/error.xml");
  2. InputStream inputStream = new FileInputStream(path);


2、在非Servlet类中(普通Java类中)的读取

在非Servlet类中,要将文件获取为流,也有两种方式:

(1)用ClassLoader类加载资源文件,这里默认是从classes目录下读取

用ClassLoader加载配置文件时,path,也就是这里的 "error.xml" 不能以"/"开头,在查找时直接在classpath下进行查找:
  1. InputStream in = ClassName.class.getClassLoader().getResourceAsStream("error.xml");

同样的方法,也可以迂回一下,先读取到文件的路径,再用流读出,这里FileInputStream的path就可以使用绝对或者相对路径:
  1. String path = ClassName.class.getClassLoader().getResource("error.xml").getPath();
  2. InputStream inputStream = new FileInputStream(path);


(2)用Class类加载资源文件
  1. InputStream inputStream = ClassName.class.getResourceAsStream("/error.xml");
需要注意的是,这种方式的形参有两种方式:
  • 绝对定位,“/”开头,此时即以classpath为根目录
  • 相对定位,不加“/”,则以调用getResourceAsStream类的包路径作为根目录(即该类所在包下获取资源)


最后,也就是用了如上的方法,解决了我读取error.xml的问题:
  1. //读取errorCode错误码到Map中
  2. static {
  3. InputStream xml = WeChatUtil.class.getResourceAsStream("/error.xml");
  4. SAXReader saxReader = new SAXReader();
  5. try {
  6. Document document = saxReader.read(xml);
  7. Element root = document.getRootElement();
  8. List<Element> elements = root.elements();
  9. for (Element element : elements) {
  10. String code = element.elementText("code");
  11. String text = element.elementText("text");
  12. WeChatUtil.errorCodeMap.put(code, text);
  13. }
  14. } catch (DocumentException e) {
  15. log.debug("error.xml读取失败");
  16. e.printStackTrace();
  17. }
  18. }


3、参考链接

  • java web中读取properties文件时的路径问题
  • Java加载资源文件的两种方法
  • 为什么classes目录要放在WEB-INF目录下?
  • java web工程中读取properties文件,路径一直不知道怎么写
  • javaWeb项目的classpath说明


题外话:

在使用Spring时通常看到诸如 <param-value>classpath:applicationContext-*.xml</param-value> 的配置,此处的classpath确实是指WEB-INF下的classes目录,但此处毕竟只是配置的字符串,实际上获取资源路径时是框架进行了识别和处理的。我之前也是很愚,一直不理解所谓的classpath,今天才明白了些许,顺便追了下Spring源码。

在Spring的配置中,实际上有classpath和classpath*,区别在于:
  • classpath     只会到你的classes路径中查找找文件
  • classpath*    不仅包含classes路径,还包括jar文件中(class路径)进行查找


读取配置文件的正确姿势(关于配置文件的路径获取)