本文記錄學習在SpringBoot中發送郵件。
一 郵件發送過程
發送郵件是一個我們在項目中經常會用到的功能,如在用戶注冊時發送驗證碼,賬戶激活等都會用到。完整的一個郵件發送過程主要包含以下幾個步驟:
1 發件人在用戶郵件代理上寫郵件內容及收件人的郵箱地址;
2 用戶郵件代理根據發件人填寫的郵件信息,生成一封符合郵件格式的郵件;
3 用戶郵件代理把郵件發送到發信人的郵件服務器上;
4 發件人的郵件服務器使用 SMTP 協議把這封郵件發送到收件人的郵件服務器上;
5 收件人的郵件服務器收到郵件后,把這封郵件放到收件人在這個服務器上的信箱中;
6 收件人使用用戶郵件代理來收取郵件。
二 發送郵件示例
以前發送郵件時,調用 JavaMail 的相關 API 來開發實現,需要我們自己去組裝消息體,代碼量比較大,實現起來也不是很容易;Spring 提供的JavaMailSender 對JavaMail的Api做了一定的封裝,簡化了發郵件的過程。JavaMailSender 提供了強大的郵件發送功能,可支持各種類型的郵件發送。Spring Boot在JavaMailSender 的基礎上又做了進一步的封裝,讓我們的使用更加的簡單。
在pom.xml文件中引入需要得依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
在application.properties中配置郵件服務相關信息(測試使用得是QQ郵件服務)
# Email
#郵件默認字符集
spring.mail.default-encoding=UTF-8
#郵件服務地址
spring.mail.host=smtp.qq.com
#郵件服務協議,可以不寫(查看源碼可知,沒有時默認值是smtp )
#spring.mail.protocol=smtp
#端口
spring.mail.port=25
#賬號
spring.mail.username=********@qq.com
#密碼 使用第三方發送郵件時,需要開通授權,所以此處要寫郵箱授權碼
spring.mail.password=****************
完成了上邊得配置后,在啟動服務得時候,SpringBoot會根據我們得配置,為我們初始化好一個JavaMailSender類供我們調用,我們只需要在要使用得地方注入就可以了。
定義一個郵件服務接口,提供我們得郵件服務方法,其他業務中用到發郵件功能時,調用找個接口就可以了
public interface EmailSenderService {
/**
* 發送文本消息
* @param subject 郵件主題
* @param content 郵件內容
* @param to 收件人(可變參數,多個時用逗號隔開)
*/
void sendTextMail(String subject, String content, String... to);
}
@Service
public class EmailSenderServiceImpl implements EmailSenderService {
@Autowired
private JavaMailSender javaMailSender;
//發件人郵箱
@Value("${spring.mail.username}")
private String from;
@Override
public void sendTextMail(String subject, String content, String... to) {
SimpleMailMessage mailMessage = new SimpleMailMessage();
mailMessage.setFrom(from);
mailMessage.setTo(to);
mailMessage.setSubject(subject);
mailMessage.setText(content);
mailMessage.setSentDate(new Date());
javaMailSender.send(mailMessage);
}
}
如上,我們在實現類中注入JavaMailSender后直接調用它send方法就可以完成發郵件。其他業務中用到發郵件業務了,直接調用EmailSenderService 接口得方法即可。我們完全也可以把JavaMailSender直接注入到我們得各個業務模塊中去,在發郵件時直接調用JavaMailSender得send方法發郵件。但是還是推薦將郵件發送相關功能獨立起來,便於維護。
上邊我們實現了發送一個文本郵件,有時候我們還需要在發送郵件時附帶發送附件,這種也是支持的,我們添加接口及實現方法
/**
* 發送帶附件郵件
* @param subject 主題
* @param content 內容
* @param filePath 附件得本地路徑
* @param fileName 附件名
* @param to 收件人
*/
void sendAttachmentMail(String subject, String content, String filePath, String fileName, String... to);
@Override
public void sendAttachmentMail(String subject, String content, String filePath, String fileName, String... to) {
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
try {
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(content);
//附件
FileSystemResource file = new FileSystemResource(new File(filePath));
helper.addAttachment(fileName, file);
javaMailSender.send(mimeMessage);
} catch (MessagingException e) {
e.printStackTrace();
}
}
如果我們發送郵件時,除了收件人之外,還想讓某些人知道即抄送某些人,這種也是支持得,接口及實現方法如下:
/**
* 發送一個郵件並抄送
* @param subject 主題
* @param content 內容
* @param ccList 抄送人(可以有多個)
* @param to 收件人(可以有多個)
*/
void sendTextMail(String subject, String content, List<String> ccList, String... to);
@Override
public void sendTextMail(String subject, String content, List<String> ccList, String... to) {
//收件人地址
InternetAddress[] addressesTo = new InternetAddress[to.length];
if(to != null && to.length>0){
for(int i=0;i<to.length;i++){
InternetAddress addressTo = null;
try {
addressTo = new InternetAddress(to[i]);
addressesTo[i] = addressTo;
} catch (AddressException e) {
e.printStackTrace();
}
}
}
//抄送人地址
InternetAddress[] addressesCc = new InternetAddress[ccList.size()];
if(ccList != null && ccList.size() > 0){
for(int i=0;i<ccList.size();i++){
String ccAdd = ccList.get(i);
InternetAddress address = null;
try {
address = new InternetAddress(ccAdd);
addressesCc[i] = address;
} catch (AddressException e) {
e.printStackTrace();
}
}
}
MimeMessagePreparator preparator = new MimeMessagePreparator() {
@Override
public void prepare(MimeMessage mimeMessage) throws Exception {
mimeMessage.setFrom(from);
mimeMessage.setSubject(subject);
mimeMessage.setText(content);
mimeMessage.setRecipients(Message.RecipientType.TO, addressesTo);
mimeMessage.setRecipients(Message.RecipientType.CC, addressesCc);
}
};
javaMailSender.send(preparator);
}
如上方法就實現了向多人發送郵件並且抄送多人