SpringBoot 整合邮件服务
开发中,经常需要及时通知用户消息,常见的方式有两种:邮件、短信
这里我们使用邮件服务,因为可以免费使用
SMTP简介
SMTP是一种提供可靠且有效的电子邮件传输的协议。SMTP是建立在FTP文件传输服务上的一种邮件服务,主要用于系统之间的邮件信息传递,并提供有关来信的通知。SMTP独立于特定的传输子系统,且只需要可靠有序的数据流信道支持,SMTP的重要特性之一是其能跨越网络传输邮件,即“SMTP邮件中继”。使用SMTP,可实现相同网络处理进程之间的邮件传输,也可通过中继器或网关实现某处理进程与其他网络之间的邮件传输。
简单来说:我们使用的这些邮件发送功能,他们之间都有一个专门的电子邮件的服务器,类似于邮局,你将邮件发给邮局,邮局又会根据你的邮寄地址发送给相应的邮局,然后接收方去邮局取邮件。而邮件服务器呢,就是互联网之间的一个邮局,不同的网络之间也能实现电子邮件的发送。
SpringBoot使用
引入依赖
pom.xml 中添加
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
yml设置邮件服务
application.yml 配置
mail:
# 配置 SMTP 服务器地址
host: smtp.qq.com
# 发送者邮箱
username: *******@qq.com
# 配置密码,注意不是真正的密码,而是刚刚申请到的授权码
password: *******
# 端口号465或587
port: 587
# 默认的邮件编码为UTF-8
default-encoding: UTF-8
# 配置SSL 加密工厂
properties:
mail:
smtp:
socketFactoryClass: javax.net.ssl.SSLSocketFactory
#表示开启 DEBUG 模式,这样,邮件发送过程的日志会在控制台打印出来,方便排查错误
代码中使用
邮箱工具类
这里我使用mongodb的gridFS服务提供附件,不需要附件可以删除相关代码或替换自己的文件方法
import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSDownloadStream;
import com.mongodb.client.gridfs.model.GridFSFile;
import com.zykj.business.entity.mongo.FileModel;
import com.zykj.business.entity.pojo.MailPojo;
import com.zykj.business.repository.FileRepository;
import lombok.SneakyThrows;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.gridfs.GridFsResource;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.mail.internet.MimeMessage;
import java.io.InputStream;
import java.util.Date;
import java.util.Optional;
/**
* @author sungang
* 邮箱工具类
*/
@Service
public class MailService {
@Value("${spring.mail.username}")
String fromUser;
@Resource
JavaMailSender javaMailSender;
@Resource
private FileRepository fileRepository;
@Resource
private GridFsTemplate gridFsTemplate;
@Resource
private GridFSBucket fsBucket;
/**
* 普通邮件发送,立即发送
*/
public void sendSimpleMail(MailPojo mailPojo) {
// 构建一个邮件对象
SimpleMailMessage message = new SimpleMailMessage();
// 设置邮件主题
message.setSubject(mailPojo.getTitle());
// 设置邮件发送者,这个跟application.yml中设置的要一致
message.setFrom(fromUser);
// 设置邮件接收者,可以有多个接收者,中间用逗号隔开,以下类似
message.setTo(mailPojo.getSentTo());
// 设置邮件抄送人,可以有多个抄送人
message.setCc(mailPojo.getCc());
// 设置邮件发送日期
message.setSentDate(new Date());
// 设置邮件的正文
message.setText(mailPojo.getText());
// 发送邮件
javaMailSender.send(message);
}
@SneakyThrows
public void sendMineMail(MailPojo mailPojo) {
//1、创建一个复杂的邮件
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
// 设置邮件发送日期
mimeMessage.setSentDate(new Date());
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
//邮件主题
helper.setSubject(mailPojo.getTitle());
//邮件内容
helper.setText(mailPojo.getText(),true);
helper.setTo(mailPojo.getSentTo());
helper.setFrom(fromUser);
String[] fileIds = mailPojo.getFileIds();
if(fileIds!=null){
for (String fileId : fileIds
) {
Optional<FileModel> fileInfoByName = fileRepository.findById(fileId);
if (!fileInfoByName.isPresent()) {
return;
}
FileModel fileModel = fileInfoByName.get();
String objectId = fileModel.getFsId();
Query query = Query.query(Criteria.where("_id").is(objectId));
GridFSFile file = gridFsTemplate.findOne(query);
if (file != null) {
String contentType = fileModel.getContentType();
GridFSDownloadStream in = fsBucket.openDownloadStream(file.getObjectId());
GridFsResource resource = new GridFsResource(file, in);
InputStream inputStream = resource.getInputStream();
//添加附件
helper.addAttachment(fileModel.getName(), new ByteArrayResource(IOUtils.toByteArray(inputStream)), contentType);
}
}
}
javaMailSender.send(mimeMessage);
}
}
邮箱实体类
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @author sungang
* @date 2021/11/3 11:06 上午
*/
@Data
public class MailPojo {
//邮件接收者,可以有多个接收者,中间用逗号隔开
private String[] sentTo;
//邮件抄送者,可以有多个接收者,中间用逗号隔开
private String[] cc;
//邮件主题
private String title;
//邮件内容
private String text;
//文件
private String[] fileIds;
}
在需要发送消息的地方调用方法即可
@Resource
public MailService mailService;
MailPojo mailPojo = new MailPojo();
mailPojo.setTitle("title");
String[] mails = {"132****@qq.com","133****@qq.com"};
mailPojo.setSentTo(mails);
mailPojo.setText("text");
mailService.sendSimpleMail(mailPojo);