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

SpringBoot从2.5升级到3.2后PDF文件下载失败求助

SpringBoot 3.2迁移后iText7生成PDF下载异常问题

问题描述

SpringBoot从2.5版本迁移至3.2版本后,使用itext7-core:7.2.2生成的PDF出现下载异常:

  • 浏览器内直接查看PDF无异常
  • 下载的文件没有扩展名,手动添加.pdf后打开发现内容是网页源码(并非生成PDF的页面源码)
  • 迁移时仅将代码中的javax.servlet.http.HttpServletResponse替换为jakarta.servlet.http.HttpServletResponse,原有代码在SpringBoot 2.5下运行正常

核心代码片段

public void pdfgeneration(HttpServletRequest request, HttpServletResponse response)
           throws IOException, ServletException {
try {
           ByteArrayOutputStream ba = new ByteArrayOutputStream();
           PdfWriter writer = new PdfWriter(ba);
           PdfDocument pdfDocument = new PdfDocument(writer);
           Document document = new Document(pdfDocument, PageSize.A4, false);

           PdfDocumentInfo pdfMetaData = pdfDocument.getDocumentInfo();
           pdfMetaData.setTitle(Constants.TITLE);
           pdfMetaData.setAuthor(Constants.AUTHOR);
           pdfMetaData.setSubject(Constants.SUBJECT);
           pdfMetaData.setProducer("");
           // ... 省略PDF内容生成逻辑
           document.close();
           response.setHeader("Expires","0");
           response.setHeader("Cache-Control", "must-revalidate,post-check=0,pre-check=0");
           response.setHeader("Pragma", "public");
           response.setContentType("application/pdf");
           response.setContentLength(ba.size());
           OutputStream outy = response.getOutputStream();
           ba.writeTo(outy);
           outy.flush();
           outy.close();
} catch(Exception e){
           // ... 省略异常处理逻辑
}
}

解决方案建议

1. 添加Content-Disposition头指定下载文件名

缺少文件名头会导致浏览器无法识别文件类型,甚至触发错误页面跳转。在setContentType之后添加以下代码:

response.setHeader("Content-Disposition", "attachment; filename=\"generated.pdf\"");

filename参数用双引号包裹,避免文件名包含空格或特殊字符时出现解析问题。

2. 修复异常处理逻辑

原catch块未明确终止响应,可能在SpringBoot 3.2中,异常发生后后续页面控制器接管了响应,返回网页内容。修改catch块:

catch (Exception e) {
    e.printStackTrace();
    // 明确返回错误响应,阻止后续处理
    response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "PDF生成失败");
    return;
}

3. 不要手动关闭响应输出流

Jakarta EE下Spring容器会管理响应流的生命周期,手动调用outy.close()可能导致容器后续处理响应出错,返回错误页面。移除该行代码:

ba.writeTo(outy);
outy.flush();
// 移除 outy.close();

4. 移除手动设置的Content-Length

document.close()后,ByteArrayOutputStream的大小可能并非最终PDF的真实大小(iText7在close时可能还有收尾写入),手动设置的Content-Length可能导致浏览器接收内容不完整,触发错误处理。注释掉该代码:

// response.setContentLength(ba.size());

让Spring容器自动计算并设置Content-Length头。

5. 升级iText7版本

虽然7.2.2支持Jakarta EE,但新版本可能修复了更多兼容性问题,尝试升级到最新稳定版(如7.2.5),修改Maven依赖:

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext7-core</artifactId>
    <version>7.2.5</version>
    <type>pom</type>
</dependency>

内容的提问来源于stack exchange,提问作者Sayak-

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 13:35:35