You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 11:06:02