1、获取邮箱授权码
以QQ邮箱为例,登录QQ邮箱网页版后,点击进入"设置"-"安全设置"选项。

2、集成JavaMail
官方文档:https://docs.spring.io/spring-framework/reference/integration/email.html
2.1、引入依赖
XML
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
2.2、添加配置
java
spring:
# 邮件配置
mail:
# 邮件服务器地址
host:
# 邮件发送者
username:
# 授权码
password:
properties:
mail:
smtp:
# 是否启用 SMTP 验证
auth: true
starttls:
# 是否启用TLS加密
enable: true
2.3、创建邮箱对象
java
@Data
public class Email implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 必填
* 邮件接收方
*/
private String[] to;
/**
* 必填
* 邮件主题
*/
private String subject;
/**
* 可选
* 邮件内容
*/
private String text;
/**
* 可选
* 附件路径
*/
private List<String> filePathList;
/**
* 可选
* 图片路径
*/
private List<String> imagePathList;
}
2.4、邮箱格式校验
java
public class EmailUtils {
// 定义用于匹配大多数有效电子邮件地址的正则表达式
private static final String EMAIL_REGEX =
"^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$";
// 编译正则表达式
private static final Pattern emailPattern = Pattern.compile(EMAIL_REGEX);
/**
* 校验给定的email是否合法
* @param email 待校验的电子邮件地址
* @return 如果电子邮件地址合法返回true,否则返回false
*/
public static boolean isValidEmail(String email) {
if (email == null) {
return false;
}
Matcher matcher = emailPattern.matcher(email);
return matcher.matches();
}
}
2.5、发送内容为文本的邮件
java
@Component
public class SendMail {
private static final Logger log = LoggerFactory.getLogger(SendMail.class);
@Value("${spring.mail.username}")
private String from;
@Autowired
private JavaMailSender javaMailSender;
/**
* 发送内容为文本的邮件
**/
public boolean sendSimpleMail(Email email) {
try {
checkEmail(email);
//创建简单邮件消息
SimpleMailMessage message = new SimpleMailMessage();
//发送人
message.setFrom(from);
//接收人
message.setTo(email.getTo());
//邮件主题
message.setSubject(email.getSubject());
//邮件内容
message.setText(email.getText());
//发送邮件
javaMailSender.send(message);
} catch (Exception e) {
log.error("邮件发送失败:{}", email, e);
return false;
}
log.error("邮件发送成功:{}", Arrays.toString(email.getTo()));
return true;
}
}
2.6、发送内容为html的邮件
java
@Component
public class SendMail {
private static final Logger log = LoggerFactory.getLogger(SendMail.class);
@Value("${spring.mail.username}")
private String from;
@Autowired
private JavaMailSender javaMailSender;
/**
* 发送内容为html的邮件
**/
public boolean sendMimeMail(Email email) {
try {
checkEmail(email);
//创建MINE邮件消息
MimeMessage message = javaMailSender.createMimeMessage();
MimeMessageHelper mineHelper = new MimeMessageHelper(message, true);
//发送人
mineHelper.setFrom(from);
//接收人
mineHelper.setTo(email.getTo());
//邮件主题
mineHelper.setSubject(email.getSubject());
//邮件内容,true 表示带有附件或html
mineHelper.setText(email.getText(),true);
//发送邮件
javaMailSender.send(message);
} catch (Exception e) {
log.error("邮件发送失败:{}", email, e);
return false;
}
log.error("邮件发送成功:{}", Arrays.toString(email.getTo()));
return true;
}
}
2.7、发送内容为图片的邮件
内联资源通过使用指定的Content-ID添加到MimeMessage。添加文本和资源的顺序非常重要。一定要先添加文本,然后再添加资源。如果你用另一种方式来做,它是行不通的。
java
@Component
public class SendMail {
private static final Logger log = LoggerFactory.getLogger(SendMail.class);
@Value("${spring.mail.username}")
private String from;
@Autowired
private JavaMailSender javaMailSender;
/**
* 发送内容为图片的邮件
**/
public boolean sendImageMail(Email email) {
try {
checkEmail(email);
//创建MINE邮件消息
MimeMessage message = javaMailSender.createMimeMessage();
MimeMessageHelper mineHelper = new MimeMessageHelper(message, true);
//发送人
mineHelper.setFrom(from);
//接收人
mineHelper.setTo(email.getTo());
//邮件主题
mineHelper.setSubject(email.getSubject());
if (CollectionUtils.isNotEmpty(email.getImagePathList())) {
StringBuilder htmlContent = new StringBuilder();
htmlContent.append("<html><body>");
for(int i = 0; i < email.getImagePathList().size(); i++){
String imagePath = email.getImagePathList().get(i);
File file = new File(imagePath);
if (!file.exists()) {
log.error("图片不存在:{}", imagePath);
continue;
}
String contentId = "identifier" + i;
htmlContent.append("<img src='cid:").append(contentId).append("' style='max-width:600px;display:block;margin-bottom:10px;'/>");
}
htmlContent.append("</body></html>");
//邮件内容,true 表示带有附件或html
mineHelper.setText(htmlContent.toString(),true);
for(int i = 0; i < email.getImagePathList().size(); i++){
String imagePath = email.getImagePathList().get(i);
File file = new File(imagePath);
if (!file.exists()) {
log.error("图片不存在:{}", imagePath);
continue;
}
//添加内联资源,一个id对应一个资源,最终通过id来找到该资源
String contentId = "identifier" + i;
FileSystemResource resource = new FileSystemResource(file);
mineHelper.addInline(contentId, resource);
}
}
//发送邮件
javaMailSender.send(message);
} catch (Exception e) {
log.error("邮件发送失败:{}", email, e);
return false;
}
log.error("邮件发送成功:{}", Arrays.toString(email.getTo()));
return true;
}
}
2.7、发送内容为文本且包含图片的邮件
java
@Component
public class SendMail {
private static final Logger log = LoggerFactory.getLogger(SendMail.class);
@Value("${spring.mail.username}")
private String from;
@Autowired
private JavaMailSender javaMailSender;
/**
* 发送内容为文本且包含图片的邮件
**/
public boolean sendTextImageMail(Email email) {
try {
checkEmail(email);
//创建MINE邮件消息
MimeMessage message = javaMailSender.createMimeMessage();
MimeMessageHelper mineHelper = new MimeMessageHelper(message, true);
//发送人
mineHelper.setFrom(from);
//接收人
mineHelper.setTo(email.getTo());
//邮件主题
mineHelper.setSubject(email.getSubject());
if (CollectionUtils.isNotEmpty(email.getImagePathList())) {
StringBuilder htmlContent = new StringBuilder();
htmlContent.append("<html><body>");
htmlContent.append("<div>").append(email.getText()).append("</div>");
for(int i = 0; i < email.getImagePathList().size(); i++){
String imagePath = email.getImagePathList().get(i);
File file = new File(imagePath);
if (!file.exists()) {
log.error("图片不存在:{}", imagePath);
continue;
}
String contentId = "identifier" + i;
htmlContent.append("<img src='cid:").append(contentId).append("' style='max-width:600px;display:block;margin-bottom:10px;'/>");
}
htmlContent.append("</body></html>");
//邮件内容,true 表示带有附件或html
mineHelper.setText(htmlContent.toString(),true);
for(int i = 0; i < email.getImagePathList().size(); i++){
String imagePath = email.getImagePathList().get(i);
File file = new File(imagePath);
if (!file.exists()) {
log.error("图片不存在:{}", imagePath);
continue;
}
//添加内联资源,一个id对应一个资源,最终通过id来找到该资源
String contentId = "identifier" + i;
FileSystemResource resource = new FileSystemResource(file);
mineHelper.addInline(contentId, resource);
}
}else{
mineHelper.setText(email.getText());
}
//发送邮件
javaMailSender.send(message);
} catch (Exception e) {
log.error("邮件发送失败:{}", email, e);
return false;
}
log.error("邮件发送成功:{}", Arrays.toString(email.getTo()));
return true;
}
}
2.8、发送带附件的邮件
java
@Component
public class SendMail {
private static final Logger log = LoggerFactory.getLogger(SendMail.class);
@Value("${spring.mail.username}")
private String from;
@Autowired
private JavaMailSender javaMailSender;
/**
* 发送带附件的邮件
* 邮件内容可以为文本或html
**/
public boolean sendAttachmentMail(Email email) {
try {
checkEmail(email);
//创建MINE邮件消息
MimeMessage message = javaMailSender.createMimeMessage();
MimeMessageHelper mineHelper = new MimeMessageHelper(message, true);
//发送人
mineHelper.setFrom(from);
//接收人
mineHelper.setTo(email.getTo());
//邮件主题
mineHelper.setSubject(email.getSubject());
//邮件内容,true 表示带有附件或html
mineHelper.setText(email.getText(),true);
// 添加附件
if (CollectionUtils.isNotEmpty(email.getFilePathList())) {
for (String filePath : email.getFilePathList()) {
File file = new File(filePath);
if (!file.exists()) {
log.error("附件不存在:{}", filePath);
continue;
}
FileSystemResource resource = new FileSystemResource(file);
mineHelper.addAttachment(Objects.requireNonNull(resource.getFilename()), resource);
}
}
//发送邮件
javaMailSender.send(message);
} catch (Exception e) {
log.error("邮件发送失败:{}", email, e);
return false;
}
log.error("邮件发送成功:{}", Arrays.toString(email.getTo()));
return true;
}
}
2.9、checkEmail方法
java
/**
* 校验邮件
**/
private static boolean checkEmail(Email email) {
log.error("开始发送邮件:{}", email);
if (email == null) {
log.error("邮件参数错误:{}", (Object) null);
return false;
}
if (email.getTo() == null || email.getTo().length == 0) {
log.error("邮件接收人不能为空:{}", email);
return false;
}
if (StringUtils.isEmpty(email.getSubject())) {
log.error("邮件主题不能为空:{}", email);
return false;
}
for (String to : email.getTo()) {
if (!EmailUtils.isValidEmail(to)) {
log.error("邮件接收人格式错误:{}", to);
return false;
}
}
return true;
}
3、在业务中怎么使用
在其他服务中直接注入SendMail即可
java
@Autowired
private SendMail sendMail;
3.1、发送内容为文本的邮件
java
Email email = new Email();
email.setTo(new String[]{"ceshi@qq.com"});
email.setSubject("测试邮件");
email.setText("测试邮件");
boolean b = sendMail.sendSimpleMail(email);
System.out.println(b);
3.2、发送内容为html的邮件
java
Email email = new Email();
email.setTo(new String[]{"ceshi@qq.com"});
email.setSubject("测试邮件");
email.setText("<html><body><h1>测试邮件</h1></body></html>");
boolean b = sendMail.sendMimeMail(email);
System.out.println(b);
3.3、发送内容为图片的邮件
java
Email email = new Email();
email.setTo(new String[]{"ceshi@qq.com"});
email.setSubject("测试邮件");
email.setImagePathList(Arrays.asList("c:\\ceshi.jpg");
boolean b = sendMail.sendImageMail(email);
System.out.println(b);
3.4、发送内容为文本且包含图片的邮件
java
Email email = new Email();
email.setTo(new String[]{"ceshi@qq.com"});
email.setSubject("测试邮件");
email.setText("测试邮件");
email.setImagePathList(Arrays.asList("c:\\ceshi.jpg");
boolean b = sendMail.sendTextImageMail(email);
System.out.println(b);
3.5、发送带附件的邮件
java
Email email = new Email();
email.setTo(new String[]{"ceshi@qq.com"});
email.setSubject("测试邮件");
email.setText("测试邮件");
email.setFilePathList(Arrays.asList("c:\\ceshi.jpg");
boolean b = sendMail.sendAttachmentMail(email);
System.out.println(b);