在Java项目打包成JAR运行后,内部的XML资源文件不再以普通文件形式存在于磁盘中,而是被封装在JAR包的文件结构里,因此不能用常规的File类通过绝对路径或相对路径读取。我们需要借助类加载器或者类本身的资源获取方法来定位并读取这些资源。
使用ClassLoader读取JAR内XML资源
ClassLoader是类加载器,它可以加载类路径下的所有资源,包括JAR包内的资源。这种方式适合读取类路径下任意位置的XML文件,不需要依赖具体的类实例。
实现步骤如下:
- 获取当前线程的上下文类加载器,或者获取某个类的ClassLoader
- 调用类加载器的
getResourceAsStream方法,传入XML资源在类路径下的相对路径 - 通过输入流读取XML内容
示例代码如下:
import java.io.InputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
public class JarXmlReader {
public static void main(String[] args) {
try {
// 获取类加载器,这里使用当前类的ClassLoader
ClassLoader classLoader = JarXmlReader.class.getClassLoader();
// XML资源放在src/main/resources/config目录下,路径不需要开头的/
InputStream inputStream = classLoader.getResourceAsStream("config/app_config.xml");
if (inputStream == null) {
System.out.println("未找到XML资源文件");
return;
}
// 解析XML输入流
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(inputStream);
// 输出XML根节点名称
System.out.println("XML根节点:" + document.getDocumentElement().getNodeName());
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
使用Class类的getResourceAsStream方法读取
Class类的getResourceAsStream方法也可以读取资源,它的路径规则和资源所在的类路径相关,分为两种路径写法:
- 路径以
/开头:表示从类路径的根目录开始查找资源 - 路径不以
/开头:表示从当前类所在的包路径下开始查找资源
示例代码如下:
import java.io.InputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
public class JarXmlReader2 {
public static void main(String[] args) {
try {
// 以/开头,从类路径根目录查找resources下的xml文件
InputStream inputStream = JarXmlReader2.class.getResourceAsStream("/config/app_config.xml");
if (inputStream == null) {
System.out.println("未找到XML资源文件");
return;
}
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(inputStream);
System.out.println("XML根节点:" + document.getDocumentElement().getNodeName());
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Web项目中读取JAR内XML资源
如果是Web项目,JAR包放在WEB-INF/lib目录下,还可以通过ServletContext来获取资源流,这种方式适合在Servlet、Spring MVC等Web组件中使用。
示例代码如下:
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import java.io.InputStream;
public class WebXmlReaderServlet extends HttpServlet {
@Override
public void init() {
try {
ServletContext context = getServletContext();
// 路径从Web应用的根目录开始,JAR内的资源需要通过类路径方式获取,这里结合ClassLoader使用
InputStream inputStream = context.getResourceAsStream("/WEB-INF/classes/config/app_config.xml");
if (inputStream == null) {
// 也可以直接用ClassLoader获取
inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("config/app_config.xml");
}
if (inputStream != null) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(inputStream);
System.out.println("Web项目读取XML根节点:" + document.getDocumentElement().getNodeName());
inputStream.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
注意事项
- JAR包内的资源是只读的,不能通过输出流修改内容,否则会抛出异常
- 路径不要写错,ClassLoader的
getResourceAsStream方法路径不需要开头的/,而Class的getResourceAsStream方法以/开头时才是类路径根目录 - 读取完成后一定要关闭输入流,避免资源泄露
- 如果资源不存在,
getResourceAsStream方法会返回null,需要做非空判断,避免空指针异常
JavaXML资源读取JAR包ClassLoader修改时间:2026-06-11 11:09:31