Spring Boot项目Swagger UI下载Zip文件文件名异常问题求助
解决Swagger UI调用Zip下载API时文件名不符合预期的问题
问题分析
通过Swagger UI调用API时,下载的Zip文件名称不符合Content-Disposition头设置且无扩展名,核心原因包括:
Content-Disposition头格式未遵循RFC标准,文件名未用双引号包裹,导致Swagger UI解析异常- OpenAPI配置中响应的Content-Type过于宽泛,未指定明确的压缩文件类型
- 代码中临时文件处理存在冗余且有潜在资源泄漏风险
解决方案
1. 修正Content-Disposition头格式
按照RFC 6266规范,文件名需用双引号包裹,避免特殊字符(如日期中的连字符)引发解析错误。修改代码中的头设置:
// 原代码 header.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + zipFilename); // 修改后 header.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + zipFilename + "\"");
2. 优化OpenAPI配置
将响应的Content-Type指定为application/zip,让Swagger UI更精准识别文件类型,同时明确Content-Disposition头的示例格式:
# 修改后的openapi.yml响应配置 responses: '200': description: 成功生成并下载报告 content: application/zip: schema: type: string format: binary headers: Content-Disposition: schema: type: string description: 文件附件头 example: "attachment; filename=\"Report_2024-05-20T10-30-00-000.zip\""
3. 优化临时文件处理(推荐)
原代码通过本地文件生成Zip再读取的方式冗余且有磁盘IO开销,改为内存中直接生成Zip,避免文件残留风险:
// 替换原ZipOutputStream相关代码 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); try (ZipOutputStream zipOut = new ZipOutputStream(byteArrayOutputStream)) { for (String filePath : filenames) { File fileToZip = new File(filePath); zipOut.putNextEntry(new ZipEntry(fileToZip.getName())); Files.copy(fileToZip.toPath(), zipOut); zipOut.closeEntry(); // 关闭当前Zip条目,避免资源泄漏 } } // 直接使用内存字节数组创建资源 ByteArrayResource resource = new ByteArrayResource(byteArrayOutputStream.toByteArray()); // 返回响应,无需处理本地文件删除 return ResponseEntity.ok() .headers(header) .contentLength(byteArrayOutputStream.size()) .contentType(MediaType.APPLICATION_OCTET_STREAM) .body(resource);
4. 验证效果
重启服务后在Swagger UI中调用API:
- 点击下载按钮时,浏览器应自动使用
Content-Disposition头中指定的带.zip扩展名的文件名 - 若仍有异常,可尝试清除浏览器缓存或使用隐私模式测试
内容的提问来源于stack exchange,提问作者anonymous
相关产品推荐
相关产品推荐

