Spring Boot Jar包内文档路径获取及邮件附件发送问题
解决Spring Boot Jar包中资源文件作为邮件附件的问题
问题场景
运行打包为Jar文件的Spring Boot应用,需要发送带有Jar包内部文件作为附件的邮件。最初尝试用ClassPathResource获取文件流后调用attachPart.attachFile(IOUtils.toString(inputStream)),但触发了以下错误:
javax.mail.MessagingException: IOException while sending message; nested exception is: java.io.FileNotFoundException: Invalid file path
错误原因
MimeBodyPart.attachFile()方法的设计是基于磁盘物理文件路径的,但当应用打包成Jar后,Jar内部的资源并不是磁盘上的独立文件,而是Jar归档中的一个条目。直接把流转换成字符串传入这个方法,它根本找不到对应的物理文件,自然会抛出文件找不到的异常。
正确解决方案
我们可以通过ByteArrayDataSource将资源流包装成JavaMail能识别的数据源,完全绕开对物理文件路径的依赖。修改后的核心代码如下:
if (isAttach) { // 添加附件逻辑 if (!attachFiles.isEmpty()) { for (String filePath : attachFiles) { try { // 从类路径(Jar包内)获取资源输入流 InputStream resourceStream = this.getClass().getResourceAsStream("/" + filePath); // 用ByteArrayDataSource包装流,指定附件的MIME类型(这里是pdf,可根据实际调整) DataHandler dataHandler = new DataHandler(new ByteArrayDataSource(resourceStream, "application/pdf")); MimeBodyPart attachPart = new MimeBodyPart(); attachPart.setDataHandler(dataHandler); // 给附件设置文件名,否则收件人看到的附件会没有名称 attachPart.setFileName(filePath.substring(filePath.lastIndexOf("/") + 1)); multipart.addBodyPart(attachPart); } catch (IOException ex) { ex.printStackTrace(); } } } }
关键注意点
- 确保资源路径正确:
getResourceAsStream("/" + filePath)中的斜杠表示类路径的根目录,所以你的附件文件要放在src/main/resources下,打包后才能被正确加载。 - 正确设置MIME类型:如果你的附件不是PDF,要对应修改成
image/png、application/vnd.ms-excel等合适的类型。 - 必须设置文件名:
setFileName()方法一定要调用,否则邮件里的附件会显示成无名称的文件,影响用户体验。
内容的提问来源于stack exchange,提问作者coders
相关产品推荐
相关产品推荐

