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

迁移至JakartaMail后,字节数组生成邮件附件报错求解决方案

解决JavaMail发送字节数组附件时的"Passed-in Resource contains an open stream"错误

直接用ByteArrayResource替代InputStreamResource就能解决问题,这是最优雅的方案,不需要临时文件中转。

原因分析

报错的核心问题是:InputStreamResource包装的是一个已打开的输入流,它的getInputStream()方法只会返回同一个流实例。而JavaMail在处理附件过程中,可能会多次尝试获取输入流(比如校验、读取内容),一旦流被读取过就无法再次使用,因此触发了这个错误。

而ByteArrayResource内部持有完整的字节数组,每次调用getInputStream()时都会基于该数组新建一个ByteArrayInputStream,完全满足JavaMail对“每次调用都生成新流”的要求。

修改后的代码

把你原来的附件处理代码替换成下面这段:

// 附件
byte[] data;
if (emailDTO.getIsForCheckIn()) {
    data = pdfService.generatePDFForCheckIn(emailDTO);
} else if (emailDTO.getIsForPaymentRefund()) {
    data = pdfService.generatePDFForRefund(emailDTO);
} else {
    data = pdfService.generatePDFForOnlineBooking(emailDTO);
}

String fileName = String.format("Booking-%s.pdf", emailDTO.getOnlineRentSell().get_id()).replace(":", "");
// 直接使用ByteArrayResource包装字节数组
messageHelper.addAttachment(fileName, new ByteArrayResource(data));

为什么这个方案更好

  • 不需要创建临时文件,避免了磁盘IO操作,性能更优
  • 代码更简洁,不需要手动处理输入流的创建和关闭
  • 完全符合Spring Mail和JavaMail的规范,不会出现流重复读取的问题

内容的提问来源于stack exchange,提问作者Hansjörg Hofer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 11:30:15