Spring Boot读取资源文件出现StreamCorruptedException的解决求助
问题原因分析
报错java.io.StreamCorruptedException: invalid stream header: EFBFBDEF的本质是读取的流并非合法的Java序列化对象流:
EFBFBDEF是UTF-8编码的BOM(字节顺序标记),说明你加载的文件被当成文本文件处理过,开头多出了BOM字节,而ObjectInputStream要求读取的是纯二进制序列化数据,因此无法识别流头。- 普通Maven项目能正常运行,是因为默认没有对资源文件进行文本过滤/编码转换,文件保持了原始二进制格式;而Spring Boot的Maven插件默认会对
src/main/resources下的资源进行过滤(比如替换${}占位符、转换编码),破坏了二进制文件的结构。
修复方案
1. 排除二进制资源的过滤处理
如果该资源是二进制序列化文件,在Spring Boot项目的pom.xml中配置Maven资源插件,不对目标资源文件进行过滤:
<build> <resources> <!-- 对普通资源开启过滤 --> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> <excludes> <exclude>META-INF/spring-main-cfg.xml</exclude> </excludes> </resource> <!-- 不对目标二进制资源进行过滤 --> <resource> <directory>src/main/resources</directory> <filtering>false</filtering> <includes> <include>META-INF/spring-main-cfg.xml</include> </includes> </resource> </resources> </build>
2. 移除文件的UTF-8 BOM标记
如果资源文件本身被编辑器添加了UTF-8 BOM:
- 用Notepad++、VS Code等编辑器打开文件
- 选择编码格式为「UTF-8 无BOM」,重新保存后替换原文件
3. 确认资源文件类型是否匹配
检查依赖代码中的keyFileName是否确实指向spring-main-cfg.xml:
- 若
ObjectInputStream用于读取序列化对象,该文件应该是二进制格式,而非XML文本;如果是XML文件,依赖代码应该用XML解析器读取,而非ObjectInputStream,这可能是依赖文档或你的理解有误。
4. 改用Spring Boot的资源加载方式
在Spring Boot中,推荐使用框架提供的ResourceLoader加载资源,避免类加载器可能的路径问题:
import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.io.BufferedInputStream; import java.io.ObjectInputStream; import java.io.InputStream; @Component public class ResourceLoaderExample { @Resource private ResourceLoader resourceLoader; public void loadSerializedResource() throws Exception { Resource resource = resourceLoader.getResource("classpath:META-INF/spring-main-cfg.xml"); try (InputStream in = resource.getInputStream(); ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream(in))) { // 读取序列化对象 Object obj = oin.readObject(); } } }
内容的提问来源于stack exchange,提问作者Antoine
相关产品推荐
相关产品推荐

