本文目录导读:

在Java中推送邮件消息,最经典、最常用的方式是使用 JavaMail API(jakarta.mail 或 javax.mail)。
以下我会给出几个核心的案例,从最基础的文本邮件,到带附件、HTML内容的邮件,以及基于Spring Boot的集成方式。
准备工作:引入依赖
根据你项目的构建工具和Jakarta命名空间,选择合适的依赖。
Maven(Jakarta Mail 2.x,适用于Spring Boot 3.x / Jakarta EE 9+)
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>jakarta.mail</artifactId>
<version>2.0.1</version>
</dependency>
Maven(javax.mail,适用于Spring Boot 2.x / 传统项目)
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
提示:如果你想快速测试,建议使用QQ邮箱或163邮箱的SMTP服务,需要先去邮箱设置里开启“SMTP服务”并获取授权码(不是登录密码)。
发送纯文本邮件(最基础)
这个例子展示了如何使用JavaMail API发送一封简单的文本邮件。
import jakarta.mail.*;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeMessage;
import java.util.Properties;
public class SendTextEmail {
public static void main(String[] args) {
// 1. 配置邮件服务器属性
Properties props = new Properties();
props.put("mail.smtp.auth", "true"); // 需要身份验证
props.put("mail.smtp.host", "smtp.qq.com"); // SMTP服务器地址 (QQ邮箱)
props.put("mail.smtp.port", "587"); // 端口: 587 (TLS) 或 465 (SSL)
props.put("mail.smtp.starttls.enable", "true"); // 启用TLS加密
// 2. 创建Session对象(代表邮件会话)
// 发件人邮箱地址和授权码
final String username = "your_email@qq.com";
final String password = "your_authorization_code"; // 这里是授权码,不是登录密码
Session session = Session.getInstance(props, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
try {
// 3. 创建邮件消息
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(username)); // 发件人
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse("recipient@example.com")); // 收件人
message.setSubject("Java邮件测试"); // 主题
message.setText("这是一封来自Java的测试邮件。\nHello World!"); // 正文(纯文本)
// 4. 发送邮件
Transport.send(message);
System.out.println("邮件发送成功!");
} catch (MessagingException e) {
e.printStackTrace();
System.err.println("邮件发送失败: " + e.getMessage());
}
}
}
发送HTML邮件(带样式)
如果你想让邮件更美观(比如包含表格、图片、链接),可以使用setContent方法设置HTML格式。
// ... 前面的Session创建代码与案例一相同 ...
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(username));
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse("recipient@example.com"));
message.setSubject("HTML格式的邮件");
// 关键点:设置HTML内容
String htmlContent = "<h1 style='color:blue;'>这是一个标题</h1>" +
"<p>这是一段<b>加粗</b>的文字。</p>" +
"<a href='https://www.baidu.com'>点击访问百度</a>";
message.setContent(htmlContent, "text/html; charset=UTF-8");
Transport.send(message);
发送带附件的邮件
需要用到MimeMultipart组合邮件内容。
import jakarta.mail.internet.MimeBodyPart;
import jakarta.mail.internet.MimeMultipart;
import jakarta.activation.DataHandler;
import jakarta.activation.FileDataSource;
// ... 前面的Session创建代码 ...
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(username));
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse("recipient@example.com"));
message.setSubject("带附件的测试邮件");
// 1. 创建邮件正文部分
MimeBodyPart textPart = new MimeBodyPart();
textPart.setText("请查收附件中的文件。");
textPart.setContent("请查收附件中的文件。<br><b>这是HTML内容</b>", "text/html; charset=UTF-8");
// 2. 创建附件部分
MimeBodyPart attachmentPart = new MimeBodyPart();
// 假设本地有一个文件
FileDataSource fds = new FileDataSource("/path/to/your/file.txt");
attachmentPart.setDataHandler(new DataHandler(fds));
attachmentPart.setFileName(fds.getName()); // 设置附件显示的名称
// 3. 组合成 Multipart
MimeMultipart multipart = new MimeMultipart();
multipart.addBodyPart(textPart);
multipart.addBodyPart(attachmentPart);
// 4. 设置邮件内容
message.setContent(multipart);
Transport.send(message);
使用Spring Boot发送邮件(企业级推荐)
如果你使用Spring Boot,集成邮件发送非常简单,代码量也大大减少。
添加依赖(Spring Boot Starter Mail)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
配置文件 (application.yml)
spring:
mail:
host: smtp.qq.com
port: 587
username: your_email@qq.com
password: your_authorization_code
properties:
mail:
smtp:
auth: true
starttls:
enable: true
编写发送邮件的Service
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import java.io.File;
@Service
public class EmailService {
@Autowired
private JavaMailSender mailSender;
// 发送简单文本邮件
public void sendSimpleEmail(String to, String subject, String text) {
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(to);
message.setSubject(subject);
message.setText(text);
message.setFrom("your_email@qq.com"); // 可选,默认使用配置中的username
mailSender.send(message);
}
// 发送HTML邮件或带附件的邮件
public void sendMimeEmail(String to, String subject, String htmlContent,
File attachment, String attachmentName) throws MessagingException {
MimeMessage message = mailSender.createMimeMessage();
// true 表示需要构建 multipart 消息(支持附件和内联资源)
MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
helper.setTo(to);
helper.setSubject(subject);
helper.setText(htmlContent, true); // true 表示是HTML
// 添加附件
if (attachment != null) {
helper.addAttachment(attachmentName, attachment);
}
mailSender.send(message);
}
}
在Controller中调用
@RestController
public class EmailController {
@Autowired
private EmailService emailService;
@GetMapping("/send")
public String send() {
emailService.sendSimpleEmail("recipient@example.com", "Spring Boot 邮件", "您好,这是Spring Boot发送的邮件。");
return "发送成功";
}
}
常见问题与排查
| 问题 | 可能原因及解决方法 |
|---|---|
| 535 Error: Authentication failed | 密码不对,QQ邮箱/163邮箱需要使用授权码,而不是登录密码。 |
| Connection refused / Timeout | 邮箱未开启SMTP服务。 端口错误(QQ邮箱SSL用465,TLS用587)。 防火墙或网络限制。 |
| 554 DT:SPM | 被识别为垃圾邮件,尝试不要频繁发送,内容不要太像广告。 |
| 553 Mail from must equal authorized user | 发件人地址与认证的用户名不一致,务必确保setFrom和username是同一个邮箱。 |
- 快速开发:使用Spring Boot的
JavaMailSender。 - 底层控制:直接使用JavaMail API,适合需要精细控制的场景(如自定义连接池)。
- 安全性:建议使用TLS/SSL加密(
starttls.enable=true或mail.smtp.socketFactory.port=465)。 - 授权码:始终使用邮箱的授权码,不要泄露你的邮箱密码。