AWS Lambda SpringBoot API解压Zip时entry.getName()为空问题求助
解决AWS Lambda中SpringBoot API解压Zip时ZipEntry.getName()返回空字符串的问题
问题背景
本地调试SpringBoot API时,解压Zip文件能正常通过entry.getName()获取有效文件名,但部署到AWS Lambda后,日志显示该方法返回空字符串,且使用的是同一Zip文件。
可能原因
- JDK版本差异:本地使用的JDK(如Oracle JDK)与Lambda默认的Amazon Corretto JDK对Zip格式的处理逻辑存在差异,部分特殊Zip条目在Corretto中无法解析出名称。
- Zip文件格式兼容性:部分Zip文件可能包含不符合标准的条目(如无名称的隐藏条目),本地JDK做了兼容处理,但Lambda的JDK校验更严格。
- API Gateway传输问题:API Gateway未正确配置binary media types,导致Zip文件流被Base64编码或截断,破坏了Zip条目信息。
解决方案
1. 统一JDK版本
确保本地开发环境与Lambda使用相同版本的Amazon Corretto JDK(推荐Corretto 17或21),消除版本差异带来的解析逻辑不同。
2. 替换Zip解析库为Apache Commons Compress
JDK自带的ZipInputStream对非标准Zip格式的兼容性较差,改用Apache Commons Compress的ZipArchiveInputStream能更好地处理各种Zip条目。
步骤:
- 引入Maven依赖:
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-compress</artifactId> <version>1.24.0</version> </dependency>
- 修改
unzipFile方法:
private void unzipFile(MultipartFile file, File destDir) throws IOException { String MethodName = "unzipFile():::::"; System.out.println(MethodName+"starts"); try (ZipArchiveInputStream zipInputStream = new ZipArchiveInputStream(file.getInputStream())) { System.out.println(MethodName+"inside try"); ZipArchiveEntry entry; while ((entry = zipInputStream.getNextZipEntry()) != null) { // 处理空名称的情况,生成唯一临时名称 String entryName = entry.getName(); if (entryName == null || entryName.isEmpty()) { entryName = "temp-" + UUID.randomUUID(); if (entry.isDirectory()) { entryName += "/"; } } System.out.println(MethodName+"inside while::::+"+entryName); File entryDestination = new File(destDir, entryName); System.out.println(MethodName+"entryDestination :::"+entryDestination); if (entry.isDirectory()) { System.out.println(MethodName+"inside if :::"+entry.isDirectory()); entryDestination.mkdirs(); } else { System.out.println(MethodName+"inside else :::"+entry.isDirectory()); // 确保父目录存在,避免文件创建失败 Files.createDirectories(entryDestination.getParentFile().toPath()); Files.copy(zipInputStream, entryDestination.toPath(), StandardCopyOption.REPLACE_EXISTING); } } System.out.println(MethodName+"after while :::"); } System.out.println(MethodName+"ends"); }
3. 配置API Gateway Binary Media Types
登录AWS控制台,进入对应API的Settings页面,在Binary Media Types中添加application/zip,部署API更新配置,确保Zip文件流以二进制形式正确传递到Lambda。
4. 增加日志排查
在unzipFile的循环中添加额外日志,查看Zip条目的其他属性,确认条目是否有效:
System.out.println(MethodName+"entry info - size: "+entry.getSize()+", isDirectory: "+entry.isDirectory());
验证
部署修改后的代码到Lambda,使用同一Zip文件测试,查看日志中entry.getName()是否能正常返回文件名。
内容的提问来源于stack exchange,提问作者Nandan Dubey
相关产品推荐
相关产品推荐

