Spring Boot生成PDF压缩包无法下载问题排查
问题分析
你的核心问题是通过Spring Boot Controller调用Servlet处理文件打包下载时,Servlet的响应流没有正确输出到浏览器,反而被Controller的字符串返回覆盖。日志显示流程完成说明PDF下载和ZIP打包逻辑是正常的,问题出在响应传递环节。
解决方案
放弃直接调用Servlet的方式,把PDF下载、ZIP打包的逻辑整合到Controller中,直接通过Spring的响应对象输出ZIP文件:
1. 重构核心逻辑到工具类
创建一个工具类处理PDF下载和ZIP打包:
import org.springframework.util.StreamUtils; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.net.URL; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class ZipDownloadUtil { public static void downloadAndZipPdfs(List<String> pdfUrls, HttpServletResponse response) throws IOException { // 设置响应头,触发浏览器下载 response.setContentType("application/zip"); response.setHeader("Content-Disposition", "attachment; filename=\"pdfs.zip\""); try (ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream())) { for (int i = 0; i < pdfUrls.size(); i++) { String pdfUrl = pdfUrls.get(i); try (InputStream pdfIn = new URL(pdfUrl).openStream()) { // 添加ZIP条目 ZipEntry entry = new ZipEntry("document_" + (i+1) + ".pdf"); zipOut.putNextEntry(entry); // 把PDF内容写入ZIP StreamUtils.copy(pdfIn, zipOut); zipOut.closeEntry(); } } zipOut.finish(); } } }
2. 修改Controller直接调用工具类
去掉原来调用Servlet的逻辑,让Controller直接处理响应:
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Arrays; import java.util.List; @RestController public class ZipController { @GetMapping("/hello") public void downloadZip(HttpServletResponse response) throws IOException { // 替换成你的PDF URL列表 List<String> pdfUrls = Arrays.asList( "https://example.com/pdf1.pdf", "https://example.com/pdf2.pdf" ); ZipDownloadUtil.downloadAndZipPdfs(pdfUrls, response); } }
3. 原方式失效的原因
- Servlet是独立处理请求响应的组件,你在Controller里直接调用Servlet方法时,Servlet的
response对象和Controller的response并非同一个,Servlet的输出流没有关联到浏览器的响应链路。 - 你的Controller返回了字符串“Testing zip”,这会直接覆盖响应体内容,导致浏览器仅接收该字符串,而非预期的ZIP文件。
验证要点
- 确保PDF目标URL可正常访问,不存在权限或网络连通问题。
- 直接访问
/hello接口,浏览器应自动触发ZIP文件下载。
内容的提问来源于stack exchange,提问作者Sachin Mankotia
相关产品推荐
相关产品推荐

