项目中有用到读取 XML
文件数据到 InputStream
,因对getResourceAsStream(String path)
的用法不够了解,读到的总是空,问题已解决,总结如下。
三种方式说明
首先说明是基于 SSM 框架
Class.getResourceAsStream(String path)
path:不以
/
开头默认是相对路径,指的是当前类所在的包;以/
开头指的是工程内的绝对路径,即以ClassPath
为根路径,即开发环境的src
目录,当导出war
包后,以包里面WEB-INF/classes/
为绝对根路径。通过查看该方法的原码,该方法加载文件时,调用该类的
ClassLoader
的getResourceAsStream(String path)
方法。如果ClassLoader为空,说明该class
是系统class
,就委托给ClassLoader.getSystemResourceAsStream(String path)
方法。public InputStream getResourceAsStream(String name) { name = resolveName(name); ClassLoader cl = getClassLoader0(); if (cl==null) { // A system class. return ClassLoader.getSystemResourceAsStream(name); } return cl.getResourceAsStream(name); }
注意:开发环境需要将
xml
文件放在src
根目录下,同时资源文件目录(config
)也要放一份,打成war
包后xml
文件只有一份,两个地方的xml
文件元素名必须相同,经测试值可以不同,打包和在开发环境运行所读的xml
文件来自同一个路径的文件,至于是那个路径的文件,经测试打包和运行读取的是最新修改的文件。至于为什么要这样我也没搞清楚,SpringMVC 项目如果两份少了一份,就会报空的错误;其它框架的项目的文件要怎么放还未去研究。
====备注补充:2018-02-10===
开发环境后面有试将src
目录的xml
文件删除,只保留资源目录config
里的xml
文件,运行可以跑成功,之前确实有报错,还是不明白。Class.getClassLoader.getResourceAsStream(String path)
默认不以/
开头或以/
开头,都是从ClassPath
根路径下获取资源。ServletContext.getResourceAsStream(String path)
默认从WebAPP根目录获取资源,Tomcat容器下的path是否以/
开头无所谓,当然这也和具体的容器实现有关。
方案示例代码
@Controller
@RequestMapping("/res")
public class XMLController {
@RequestMapping(value = "/xml", method = {RequestMethod.POST})
@ResponseBody
public void getXMLFileData(HttpServletRequest request){
//不以'/'开头,指向当前类所在的路径;以'/'开头指向当前'ClassPath'路径获取资源
// InputStream inputStream = this.getClass().getResourceAsStream("/student.xml");
//从'ClassPath'路径下获取资源
// InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("/student.xml");
ServletContext servletcontext = request.getSession().getServletContext();
//默认是webapp根目录下获取资源
InputStream inputStream = servletcontext.getResourceAsStream("student.xml");
}
}
注意:本文归作者所有,未经作者允许,不得转载