歡迎閱讀 Spring Boot 2 實(shí)戰(zhàn)系列 電子郵件雖然近幾年有點(diǎn)“退火”袍辞,但是在開(kāi)發(fā)中依然有舉足輕重的地位相满。在比較正式的場(chǎng)合我們依然通過(guò)電子郵件來(lái)傳遞信息和回執(zhí)。今天我們就來(lái)學(xué)一下如何在Spring Boot下發(fā)送電子郵件。
Java 發(fā)送郵件依賴(lài) jakarta 項(xiàng)目(原javaEE)提供的 jakarta.mail組件,Maven坐標(biāo):
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>jakarta.mail</artifactId>
<version>1.6.4</version>
<scope>compile</scope>
</dependency>
Spring 官方 又將其進(jìn)行進(jìn)一步封裝成開(kāi)箱即用的 spring-boot-starter-mail 項(xiàng)目:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
在 Spring Boot 項(xiàng)目中我們引入上面的 spring-boot-starter-mail依賴(lài)即可為你的項(xiàng)目集成郵件功能。接下來(lái)我們來(lái)對(duì)郵件功能進(jìn)行參數(shù)配置扇丛。
spring-boot-starter-mail 的配置由 MailProperties 配置類(lèi)提供。在 application.yml 配置文件中以 spring.mail 為前綴尉辑。我們來(lái)看看都有哪些配置項(xiàng)帆精。
# 字符集編碼 默認(rèn) UTF-8
spring.mail.default-encoding=UTF-8
# SMTP 服務(wù)器 host qq郵箱的為 smtp.qq.com 端口 465 587
spring.mail.host=smtp.qq.com
# SMTP 服務(wù)器端口 不同的服務(wù)商不一樣
spring.mail.port=465
# SMTP 服務(wù)器使用的協(xié)議
spring.mail.protocol=smtp
# SMTP服務(wù)器需要身份驗(yàn)證 所以 要配置用戶(hù)密碼
# 發(fā)送端的用戶(hù)郵箱名
spring.mail.username=business@felord.cn
# 發(fā)送端的密碼 注意保密
spring.mail.password=oooooxxxxxxxx
# 指定mail會(huì)話(huà)的jndi名稱(chēng) 優(yōu)先級(jí)較高 一般我們不使用該方式
spring.mail.jndi-name=
# 這個(gè)比較重要 針對(duì)不同的SMTP服務(wù)器 都有自己的一些特色配置該屬性 提供了這些配置的 key value 封裝方案 例如 Gmail SMTP 服務(wù)器超時(shí)配置 spring.mail.properties.mail.smtp.timeout= 5000
spring.mail.properties.<key> =
# 指定是否在啟動(dòng)時(shí)測(cè)試郵件服務(wù)器連接,默認(rèn)為false
spring.mail.test-connection=false
針對(duì)不同的郵箱有不同的配置隧魄,所以我們介紹幾種我們常用的郵箱配置卓练,可以直接拿來(lái)配置。
但是請(qǐng)注意很多郵箱需要手動(dòng)開(kāi)啟 SMTP 功能堤器,請(qǐng)務(wù)必確保該功能打開(kāi)昆庇。如果在公有云上部署請(qǐng)避免使用 25 端口。
# 需要開(kāi)啟 smtp
spring.mail.host=smtp.qq.com
spring.mail.port=465
# 發(fā)件人的郵箱
spring.mail.username=master@felord.cn
# qq 郵箱的第三方授權(quán)碼 并非個(gè)人密碼
spring.mail.password=qztgbzfftdwdbjcddff
#開(kāi)啟ssl 否則 503 錯(cuò)誤
spring.mail.properties.mail.smtp.ssl.enable=true
獲取授權(quán)碼的方式參見(jiàn)下圖點(diǎn)擊生成授權(quán)碼:
# 需要在設(shè)置中開(kāi)啟 smtp
spring.mail.host=smtp.163.com
spring.mail.port=465
# 發(fā)件人的郵箱
spring.mail.username=youraccount@163.com
# 郵箱的授權(quán)碼 并非個(gè)人密碼
spring.mail.password=qztgbzfftdwdbjcddff
spring.mail.properties.mail.smtp.ssl.enable=true
spring.mail.properties.mail.imap.ssl.socketFactory.fallback=false
spring.mail.properties.mail.smtp.ssl.socketFactory.class=javax.net.ssl.SSLSocketFactory
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=youraccount@gmail.com
# 安全建議使用應(yīng)用程序密碼代替Gmail密碼闸溃。參見(jiàn)相關(guān)文檔
spring.mail.password=yourpassword
# 個(gè)性配置
spring.mail.properties.mail.debug=true
spring.mail.properties.mail.transport.protocol=smtp
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.connectiontimeout=5000
spring.mail.properties.mail.smtp.timeout=5000
spring.mail.properties.mail.smtp.writetimeout=5000
# TLS , port 587
spring.mail.properties.mail.smtp.starttls.enable=true
# SSL, post 465
#spring.mail.properties.mail.smtp.socketFactory.port = 465
#spring.mail.properties.mail.smtp.socketFactory.class = javax.net.ssl.SSLSocketFactory
spring.mail.host=smtp-mail.outlook.com
spring.mail.port=587
spring.mail.username=youraccount@outlook.com
spring.mail.password=yourpassword
spring.mail.properties.mail.protocol=smtp
spring.mail.properties.mail.tls=true
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.ssl.trust=smtp-mail.outlook.com
配置完畢后我們就可以構(gòu)建我們自己的郵件發(fā)送服務(wù)了整吆。
最簡(jiǎn)單的就是發(fā)送純文本郵件了,完整代碼如下:
package cn.felord.mail.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* The Email service.
*
* @author felord.cn
* @since 2020 /1/14 23:22
*/
@Component
public class EmailService {
@Resource
private JavaMailSender javaMailSender;
@Value("${spring.mail.username}")
private String from;
/**
* 發(fā)送純文本郵件.
*
* @param to 目標(biāo)email 地址
* @param subject 郵件主題
* @param text 純文本內(nèi)容
*/
public void sendMail(String to, String subject, String text) {
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(from);
message.setTo(to);
message.setSubject(subject);
message.setText(text);
javaMailSender.send(message);
}
}
有時(shí)候我們需要在郵件中攜帶附件辉川。我們就需要發(fā)送Mime信息了表蝙,代碼如下:
/**
* 發(fā)送郵件并攜帶附件.
* 請(qǐng)注意 from 、 to 郵件服務(wù)器是否限制郵件大小
*
* @param to 目標(biāo)email 地址
* @param subject 郵件主題
* @param text 純文本內(nèi)容
* @param filePath 附件的路徑 當(dāng)然你可以改寫(xiě)傳入文件
*/
public void sendMailWithAttachment(String to, String subject, String text, String filePath) throws MessagingException {
File attachment = new File(filePath);
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper helper=new MimeMessageHelper(mimeMessage,true);
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(text);
helper.addAttachment(attachment.getName(),attachment);
javaMailSender.send(mimeMessage);
}
這里需要注意的是 from 乓旗、 to 郵件服務(wù)器是否限制郵件大小府蛇,避免郵件超出限定大小。
現(xiàn)在很多的場(chǎng)景是通過(guò)電子郵件發(fā)送宣傳營(yíng)銷(xiāo)的富文本屿愚,甚至圖文并茂帶鏈接汇跨。所以這個(gè)功能非常實(shí)用∽本啵可以通過(guò)前端編寫(xiě)適配郵件的 html 模板穷遂。將數(shù)據(jù)動(dòng)態(tài)化注入模板即可。我們先來(lái)寫(xiě)一個(gè) html :
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html" charset="UTF-8">
<title></title>
</head>
<body>
<h2>你好娱据,朋友</h2>
<div>
<p>歡迎關(guān)注公眾號(hào):<strong>Felordcn</strong></p>
<p>同時(shí)也歡迎訪問(wèn): <a >felord.cn</a></p>
<p><img src="cid:qr" alt=""></p>
</div>
</body>
</html>
上面大致上跟我們平時(shí)的 html 基本一致蚪黑,區(qū)別在于如果有內(nèi)嵌的圖片元素比如 img 標(biāo)簽 ,其 src 中需要使用占位符中剩,規(guī)則為 cid:后緊接著一個(gè)你自己定義的標(biāo)記忌穿。比如 qr 。后面會(huì)在代碼中體現(xiàn)這個(gè) qr结啼。如果使用占位符則必須指定 <meta http-equiv="content-type" content="text/html" charset="UTF-8"> 否則圖片無(wú)法顯示掠剑! 當(dāng)然你也可以直接把圖片的 url 鏈接寫(xiě)入模板,就像下面:
<html lang="en">
<body>
<h2>你好郊愧,朋友</h2>
<div>
<p>歡迎關(guān)注公眾號(hào):<strong>Felordcn</strong></p>
<p>同時(shí)也歡迎訪問(wèn): <a >felord.cn</a></p>
<p><img src="https://ae01.alicdn.com/kf/H29f220acefaa49469b5507ef296085abk.png" alt=""></p>
</div>
</body>
</html>
然后我們編寫(xiě)Java代碼澡腾,實(shí)際邏輯是4.2 章節(jié)的加強(qiáng)沸伏,如下:
/**
* 發(fā)送富文本郵件.
*
* @param to 目標(biāo)email 地址
* @param subject 郵件主題
* @param text 純文本內(nèi)容
* @param filePath 附件的路徑 當(dāng)然你可以改寫(xiě)傳入文件
*/
public void sendRichMail(String to, String subject, String text, String filePath) throws MessagingException {
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper helper=new MimeMessageHelper(mimeMessage,true);
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(text,true);
// 圖片占位寫(xiě)法 如果圖片鏈接寫(xiě)入模板 注釋下面這一行
helper.addInline("qr",new FileSystemResource(filePath));
javaMailSender.send(mimeMessage);
}
如果你采用類(lèi)似上面第二個(gè) HTML 模板,圖片邏輯就不需要了动分,注釋掉 helper.addInline() 方法即可。
今天我們對(duì) Spring Boot 發(fā)送郵件進(jìn)行了細(xì)致的歸納红选,對(duì)常用的郵箱配置進(jìn)行了列舉澜公。同時(shí)對(duì)發(fā)送各種類(lèi)型的郵件也進(jìn)行了實(shí)現(xiàn)以及細(xì)節(jié)上的探討。實(shí)際開(kāi)發(fā)中尤其要注意端口問(wèn)題和附件大小問(wèn)題喇肋。希望能對(duì)你有所幫助坟乾。喜歡對(duì)你有幫助的話(huà)記得加個(gè)關(guān)注不迷路哦
還有關(guān)注我私信回復(fù)【資料】可以領(lǐng)取到一些個(gè)人收集的面試及電子書(shū)資料,或許對(duì)你有幫助蝶防!