带附件邮件发送全指南:基于 Spring 与 Apache Commons Email 的实现
在日常开发中,带附件的邮件发送是常见需求(如报表推送、文件共享等)。本文将详细讲解两种实现方式:Spring 的 MimeMessageHelper(适合 Spring 生态项目)和 Apache Commons Email(通用 Java 项目),包括依赖配置、核心代码、参数说明及常见问题解决,帮助你快速集成邮件附件功能。
技术选型对比
| 实现方式 | 优势 | 适用场景 |
|---|---|---|
Spring MimeMessageHelper |
与 Spring 无缝集成,API 简洁,支持 HTML 内容 | Spring Boot/SSM 项目 |
| Apache Commons Email | 轻量级,无 Spring 依赖,配置灵活 | 非 Spring 项目或简单 Java 应用 |
Spring 方式:使用 MimeMessageHelper
依赖配置
需引入 Spring 邮件相关依赖(适用于 Spring 项目):
1 | <!-- Spring 邮件支持 --> |
核心代码实现
MimeMessageHelper 是 Spring 提供的邮件辅助类,支持附件、HTML 内容等功能:
1 | import org.springframework.mail.javamail.JavaMailSenderImpl; |
关键参数说明
- SMTP 服务器与端口:不同邮箱服务商的配置不同(见下表);
- 授权码:多数邮箱(如 QQ、163)需开启 SMTP 服务并生成授权码,而非使用登录密码;
- 附件处理:
addAttachment方法可多次调用添加多个附件,第一个参数为附件在邮件中显示的名称(可自定义)。
| 邮箱服务商 | SMTP 服务器 | 端口 | 备注 |
|---|---|---|---|
| QQ 邮箱 | smtp.qq.com | 587 | 需开启 SMTP 并获取授权码 |
| 163 邮箱 | smtp.163.com | 25 | 需开启 SMTP 服务 |
| 企业微信 | smtp.exmail.qq.com | 587 | 用企业邮箱账号和密码 |
| Gmail | smtp.gmail.com | 587 | 需开启 TLS 和两步验证 |
通用方式:使用 Apache Commons Email
依赖配置
适用于非 Spring 项目,引入 Apache Commons Email:
1 | <dependency> |
核心代码实现
Commons Email 封装了 JavaMail,API 更简洁:
1 | import org.apache.commons.mail.*; |
与 Spring 方式的区别
- API 风格:Commons Email 采用链式调用,更接近原生 Java 风格;
- HTML 支持:需使用
HtmlEmail子类,而 Spring 的MimeMessageHelper通过参数控制; - 附件处理:Commons Email 需通过
EmailAttachment类包装附件信息。
多附件发送与高级配置
发送多个附件
两种方式均可通过多次调用附件添加方法实现多附件发送:
1 | // Spring 方式:多次调用 addAttachment |
超大附件处理
若附件体积过大(如 >10MB),直接发送可能超时或被邮箱服务商拒绝,建议:
- 先将文件上传至云存储(如 OSS、S3),邮件中只包含下载链接;
- 拆分大文件为多个小文件,分开发送(需在邮件内容中说明)。
异步发送邮件
邮件发送可能耗时(尤其带大附件),建议通过异步方式执行,避免阻塞主线程:
1 | // Spring 异步示例(需开启 @EnableAsync) |
常见问题与解决方案
1. 认证失败(535 错误)
- 原因:密码或授权码错误,或未开启 SMTP 服务;
- 解决:
- 检查密码是否正确,多数邮箱需用 授权码(如 QQ 邮箱在 “设置 - 账户” 中开启 SMTP 并生成);
- 确认邮箱账号是否开启 SMTP 服务(登录邮箱网页版设置)。
2. 附件中文名称乱码
原因:编码设置不当;
解决:确保创建MimeMessageHelper或HtmlEmail时指定UTF-8编码:
1 | // Spring 方式 |
3. 邮件被标记为垃圾邮件
- 原因:内容含敏感词、发件人信誉低、HTML 格式不规范;
- 解决:
- 避免使用 “广告”“优惠” 等敏感词;
- 内容中增加文本说明,减少纯 HTML 代码;
- 发件人邮箱提前与收件人邮箱建立联系(如让收件人将发件人加入白名单)。
4. 发送超时
原因:网络不稳定、SMTP 服务器响应慢、附件过大;
解决:
增加超时配置:
1
2
3// Spring 方式添加超时参数
props.put("mail.smtp.connectiontimeout", "5000"); // 连接超时(毫秒)
props.put("mail.smtp.timeout", "10000"); // 发送超时(毫秒)优化附件大小(压缩或改用链接)。