参考资料
⏹依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-mailartifactId>
dependency>
⏹yml配置文件
spring:
mail:
host: smtp.qq.com
username: 1355930128@qq.com
password: 邮箱密码或者授权码
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true
⏹邮件送信
import lombok.Data;
import java.io.File;
import java.util.List;
@Data
public class MailNoticeEntity {
// 收信人List
private List<String> receiverList;
// CcList
private List<String> carbonCopyList;
// 邮件主题
private String subject;
// 邮件内容
private String content;
// 附件List
private List<File> attachmentList;
}
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import javax.annotation.Resource;
import javax.mail.internet.MimeMessage;
import java.io.File;
import java.util.List;
@Component
public class MailUtil {
@Resource
private JavaMailSender mailSender;
@Value("${spring.mail.username}")
private String sendMailAddress;
/**
* 给指定人发送邮件
* @param mailReceiver 收信人邮箱地址
* @param ccList 抄送人邮箱地址List
* @param mailTitle 邮件标题
* @param mailContent 邮件内容
* @return 送信结果
*/
public Boolean sendMailToReceiver(String mailReceiver, List<String> ccList, String mailTitle, String mailContent) {
try {
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(sendMailAddress);
message.setTo(mailReceiver);
// 抄送者List
if (!ObjectUtils.isEmpty(ccList)) {
String[] ccArray = new String[ccList.size()];
ccList.toArray(ccArray);
message.setBcc(ccArray);
}
message.setSubject(mailTitle);
message.setText(mailContent);
mailSender.send(message);
} catch (Exception ex) {
System.out.println("邮件发送失败:" + ex.getMessage());
return false;
}
return true;
}
/**
* 给指定人List中的每个人都发送邮件
* @param mailReceiverList 收信人邮箱地址
* @param ccList 抄送人邮箱地址List
* @param mailTitle 邮件标题
* @param mailContent 邮件内容
* @return 送信结果
*/
public Boolean sendMailToManyReceiver(List<String> mailReceiverList, List<String> ccList, String mailTitle, String mailContent) {
try {
for (String mailReceiver : mailReceiverList) {
this.sendMailToReceiver(mailReceiver, ccList, mailTitle, mailContent);
}
} catch (Exception ex) {
return false;
}
return true;
}
/**
* 同时给若干人发送邮件
* @param mailNoticeEntity 邮件封装类
* @return 送信结果
*/
public Boolean sendMail(MailNoticeEntity mailNoticeEntity) {
List<String> receiverList = mailNoticeEntity.getReceiverList();
if (ObjectUtils.isEmpty(receiverList)) {
return false;
}
try {
MimeMessage message = mailSender.createMimeMessage();
// 附件List
List<File> attachmentList = mailNoticeEntity.getAttachmentList();
// 如果有附件,则Flag为true,否则为False
MimeMessageHelper messageHelper = new MimeMessageHelper(message, !ObjectUtils.isEmpty(attachmentList));
// 发信人
messageHelper.setFrom(sendMailAddress);
// 收信人
String[] receiverArray = new String[receiverList.size()];
receiverList.toArray(receiverArray);
messageHelper.setTo(receiverArray);
// 抄送人
List<String> carbonCopyList = mailNoticeEntity.getCarbonCopyList();
if (!ObjectUtils.isEmpty(carbonCopyList)) {
String[] carbonCopyArray = new String[carbonCopyList.size()];
carbonCopyList.toArray(carbonCopyArray);
messageHelper.setCc(carbonCopyArray);
}
// 主题
messageHelper.setSubject(mailNoticeEntity.getSubject());
// 附件
if (!ObjectUtils.isEmpty(attachmentList)) {
for (File file : attachmentList) {
messageHelper.addAttachment(file.getName(), file);
}
}
// 邮件内容
messageHelper.setText(mailNoticeEntity.getContent());
// 发送邮件
mailSender.send(message);
} catch (Exception ex) {
System.out.println("邮件发送失败:" + ex.getMessage());
return false;
}
return true;
}
}
在项目开发过程中,我们不乏会有这样的诉求:需要在执行完数据库操作后,发送消息(比如短信、邮件、微信通知等)来执行其它的操作,而这些并不是主干业务,所以一般会放在异步线程里去执行。
@TransactionalEventListener可以保证被监听的方法会在事务提交之后触发。如果出现主方法出现异常,则不会被触发.
ApplicationEventimport org.springframework.context.ApplicationEvent;
// 发送邮件事件
public final class SendMailEvent extends ApplicationEvent {
private Integer id;
public SendMailEvent(Object source, Integer id) {
super(source);
this.id = id;
}
public Integer getId() {
return id;
}
}
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;
import javax.annotation.Resource;
import java.io.File;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@Component
public class SendMailListener {
// 注入自定义邮件工具类
@Resource
private MailUtil mailUtil;
// 监听自定义的SendMailEvent事件,当事务提交之后,触发下面的sendMail
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void sendMail(SendMailEvent event) {
String mailContent = event.getSource().toString();
Integer id = event.getId();
MailNoticeEntity mailNoticeEntity = new MailNoticeEntity();
// 收件人和抄送人
List<String> mailReceiverList = Arrays.asList("fengyehong1221@foxmail.com", "fengyehong1221@163.com");
mailNoticeEntity.setReceiverList(mailReceiverList);
mailNoticeEntity.setCarbonCopyList(Collections.singletonList("1355930128@qq.com"));
// 主题和内容
mailNoticeEntity.setSubject("邮件小测试");
mailNoticeEntity.setContent(mailContent);
// 添加附件
File file1 = new File("C:\\Users\\XXX\\Desktop\\Snipaste_2022-08-27_11-45-43.png");
File file2 = new File("C:\\Users\\XXX\\Desktop\\舅妈.png");
mailNoticeEntity.setAttachmentList(Arrays.asList(file1, file2));
// 邮件发送
Boolean mailSendResult = mailUtil.sendMail(mailNoticeEntity);
if (!mailSendResult) {
System.out.println("邮件发送失败!");
return;
}
System.out.println("发送邮件,邮件的内容是:" + mailContent + ",邮件的ID是:" + id);
}
}
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.HashMap;
@Service
public class Test12Service {
// 自定义Mybatis接口
@Resource
private TestMapper12 mapper;
// 注入事件发布对象
@Resource
private ApplicationEventPublisher applicationEventPublisher;
@Transactional(rollbackFor = Exception.class)
public void insertDataToDB() throws InterruptedException {
// 向数据库内插入数据
HashMap<String, String> paramMap = new HashMap<String, String>() {{
put("code", "M005");
put("locale", "zh");
put("item", "手机");
}};
mapper.insertDataToDB(paramMap);
// 模仿数据库的耗时操作
Thread.sleep(3000);
/*
当数据库插入成功,事务正确提交之后,会发布自定义的SendMailEvent事件
事件监听
*/
applicationEventPublisher.publishEvent(new SendMailEvent("发送自定义邮件!", 110));
}
}
import java.util.HashMap;
public interface TestMapper12 {
void insertDataToDB(HashMap<String, String> paramMap);
}
DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.jmw.mapper.TestMapper12">
<insert id="insertDataToDB" parameterType="java.util.Map">
insert into i18message (code, locale, item) values (#{code}, #{locale}, #{item})
insert>
mapper>
操作之前数据库

操作之后

邮件
