Java从AWS S3下载Zip文件缺失扩展名问题求助
问题排查与修复方案
核心问题分析
你的代码存在两个关键错误,导致Zip文件下载时缺失扩展名:
- 错误将HTTP标准响应头存入自定义元数据:你把
Content-Type和Content-Disposition放到了userMetadata中,S3会为这些键添加x-amz-meta-前缀,不会作为HTTP响应头返回给浏览器。浏览器无法获取正确的文件类型和下载文件名规则,仅能靠内容嗅探识别PDF,对Zip文件则无法正确处理。 - Content-Disposition未指定文件名:即使头设置正确,仅设
attachment会让浏览器从URL中提取文件名,预签名URL的结构可能导致后缀丢失,进而被识别为文件夹。
修复代码
修改insertFile方法,将HTTP标准头直接设置到ObjectMetadata的对应属性,并明确指定带扩展名的文件名:
public String insertFile(String key, byte arr[], EnumS3FileMetaData fileMetaData) throws IOException { ByteArrayInputStream stream = null; try { System.out.println("key while storing file is " + key); ObjectMetadata objectMetadata = new ObjectMetadata(); // 直接设置标准Content-Type,而非自定义元数据 objectMetadata.setContentType(fileMetaData.value); // 从key中提取文件名,设置Content-Disposition确保下载时带完整扩展名 String fileName = key.substring(key.lastIndexOf("/") + 1); objectMetadata.setContentDisposition(String.format("attachment; filename=\"%s\"", fileName)); objectMetadata.setContentLength(arr.length); stream = new ByteArrayInputStream(arr); this.s3Client.putObject(this.bucketName, key, stream, objectMetadata); return this.getPresignedUrl(key); } catch (S3Exception e) { String errorMsg = String.format(ErrorConstants.FILE_UPLOAD_FAILURE, key); log.error(e.getMessage()); throw new FileUploadFailureException(errorMsg); } finally { if (stream != null) { stream.close(); } } }
修复说明
- 标准头设置:通过
setContentType和setContentDisposition直接设置HTTP响应头,浏览器能正确收到application/zip类型和带.zip扩展名的文件名指令。 - 文件名提取:从传入的
key中截取最后一段作为文件名(若key包含路径则自动过滤路径部分),确保下载文件名与S3存储的文件名一致。
修改后,下载Zip文件时浏览器会自动使用带.zip的文件名,无需手动添加即可正常打开。
内容的提问来源于stack exchange,提问作者Inderjeet Chawla
相关产品推荐
相关产品推荐

