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

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、参考链接

题外话:

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

在Spring的配置中,实际上有classpath和classpath*,区别在于:

  • classpath     只会到你的classes路径中查找找文件
  • classpath*    不仅包含classes路径,还包括jar文件中(class路径)进行查找
时间: 2024-10-09 19:27:58

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

读取ClassPath下resource文件的正确姿势

1.前言 为什么要写这篇文章?身为Java程序员你有没有过每次需要读取 ClassPath 下的资源文件的时候,都要去百度一下,然后看到下面的这种答案: Thread.currentThread().getContextClassLoader().getResource("ss.properties").getPath(); 亦或是: Object.class.getResourceAsStream("ss.properties"): 你复制粘贴一下然后放到自己的项

开发函数计算的正确姿势——轻松解决大依赖部署

<a name="1"></a> 前言 首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传.函数计算准备计算资源,并以弹性伸缩的方式运行用户代码,而用户只需根据实际代码运行所消耗的资源进行付费.函数计算更多信息 参考.Fun: Fun 是一个用于支持 Serverless 应用部署的工具,能帮助您便捷地管理函数计算.API 网关.

CEPH L 版集群正确姿势

很多小伙伴在安装ceph集群的时候总会遇到各种各样的问题,今天就抽出时间来,给大家讲解一下ceph集群的安装的正确姿势,更多高级课程请访问:http://edu.51cto.com/center/course/index/search?q=朱丹阳 1.关闭selinux firewalld 2.添加本地localhost解析3.配置l版本的yum 源[ceph]name=cephenabled=1priority=1gpgcheck=1gpgkey=https://download.ceph.c

开发函数计算的正确姿势 —— 使用 Fun Local 本地运行与调试

前言首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传.函数计算准备计算资源,并以弹性伸缩的方式运行用户代码,而用户只需根据实际代码运行所消耗的资源进行付费.函数计算更多信息 参考. Fun: Fun 是一个用于支持 Serverless 应用部署的工具,能帮助您便捷地管理函数计算.API 网关.日志服务等资源.它通过一个资源配置文件(template.yml),

Git 提交的正确姿势

Git 提交的正确姿势:Commit message 编写指南 SCOP范围 middleware core config plugin test type范围 Git 每次提交代码,都要写 Commit message(提交说明),否则就不允许提交. $ git commit -m "hello world" 上面代码的-m参数,就是用来指定 commit mesage 的. 如果一行不够,可以只执行git commit,就会跳出文本编译器,让你写多行. $ git commit 基

Node.js中使用redis数据库的正确姿势

Redis是一个常用的Nosql数据库,一般用来代替Memcached做缓存服务,同时它也支持数据的持久化,有着比较广泛的应用场景.在Java中使用redis我们已经比较熟悉了,那么在node.js和koa.js框架中使用Redis的正确姿势是怎样的呢? Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点: * Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载

Log4j配置文件位置+Spring中数据源配置文件位置

一.Log4j配置文件位置 1.自动加载 应用程序启动时,默认情况下会到src目录下寻找log4j.xml配置文件,若不存在,会继续寻找log4j.properties文件,只要找到其中一个就会加载该配置文件内容. 2.手动加载 如果将log4j.properties(或log4j.xml)放到其它目录下,比如下图中的位置,应用程序就不能自动加载log4j的配置文件了,因为应用程序找不到该配置文件,你需要手动加载. 需要在应用程序启动的代码中加入如下的代码: //加载config文件夹下的log

mybatis源码-解析配置文件(三)之配置文件Configuration解析(超详细, 值得收藏)

1. 简介 1.1 系列内容 本系列文章讲解的是mybatis解析配置文件内部的逻辑, 即 Reader reader = Resources.getResourceAsReader("mybatis-config.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); 其背后的逻辑. 1.2 适合对象 了解如何使用 mybatis 来访问数据库.可参看<

开发函数计算的正确姿势 —— 爬虫

在 <函数计算本地运行与调试 - Fun Local 基本用法> 中,我们介绍了利用 Fun Local 本地运行.调试函数的方法.但如果仅仅这样简单的介绍,并不能展现 Fun Local 对函数计算开发的巨大效率的提升. 这一次,我们拿一个简单的场景来举例子--开发一个简单的爬虫函数(代码参考函数计算控制台模板),介绍如何以正确姿势,从零开始,开发一个自动伸缩.按调用次数收费的 serverless 爬虫应用. 开发步骤我们将这个完整的应用拆分成多步,并且在每一步完成后,我们都会进行相应的运