Springboot整合實現(xiàn)郵件發(fā)送的原理詳解
通常在實際項目中,也有其他很多地方會用到郵件發(fā)送,比如通過郵件注冊賬戶/找回密碼,通過郵件發(fā)送訂閱信息等等。SpringBoot集成郵件服務非常簡單,通過簡單的學習即可快速掌握郵件業(yè)務類的核心邏輯和企業(yè)郵件的日常服務
開發(fā)前準備
首先注冊發(fā)件郵箱并設置客戶端授權碼,這里以QQ 免費郵箱為例,其他的郵箱的配置也大同小異。
登錄 QQ 郵箱,點擊設置->賬戶,開啟IMAP/SMTP服務,并生成授權碼。

基礎知識
電子郵件需要在郵件客戶端和郵件服務器之間,以及兩個郵件服務器之間進行郵件傳遞,那就必須要遵守一定的規(guī)則,這個規(guī)則就是郵件傳輸協(xié)議。下面我們分別簡單介紹幾種協(xié)議:
- 什么是SMTP? SMTP全稱為Simple Mail Transfer Protocol(簡單郵件傳輸協(xié)議),它是一組用于從源地址到目的地址傳輸郵件的規(guī)范,通過它來控制郵件的中轉(zhuǎn)方式。SMTP認證要求必須提供賬號和密碼才能登陸服務器,其設計目的在于避免用戶受到垃圾郵件的侵擾。
- 什么是IMAP? IMAP全稱為Internet Message Access Protocol(互聯(lián)網(wǎng)郵件訪問協(xié)議),IMAP允許從郵件服務器上獲取郵件的信息、下載郵件等。IMAP與POP類似,都是一種郵件獲取協(xié)議。
- 什么是POP3? POP3全稱為Post Office Protocol 3(郵局協(xié)議),POP3支持客戶端遠程管理服務器端的郵件。POP3常用于“離線”郵件處理,即允許客戶端下載服務器郵件,然后服務器上的郵件將會被刪除。目前很多POP3的郵件服務器只提供下載郵件功能,服務器本身并不刪除郵件,這種屬于改進版的POP3協(xié)議。
- IMAP和POP3協(xié)議有什么不同呢? 兩者最大的區(qū)別在于,IMAP允許雙向通信,即在客戶端的操作會反饋到服務器上,例如在客戶端收取郵件、標記已讀等操作,服務器會跟著同步這些操作。而對于POP協(xié)議雖然也允許客戶端下載服務器郵件,但是在客戶端的操作并不會同步到服務器上面的,例如在客戶端收取或標記已讀郵件,服務器不會同步這些操作。
用戶要在Internet上提供電子郵件功能,必須有專門的電子郵件服務器。這些郵件服務器就類似于現(xiàn)實生活中的郵局,它主要負責接收用戶投遞過來的郵件,并把郵件投遞到郵件接收者的電子郵箱中。
郵件服務器就好像是互聯(lián)網(wǎng)世界的郵局。按照功能劃分,郵件服務器可以劃分為兩種類型:
SMTP郵件服務器:用戶替用戶發(fā)送郵件和接收外面發(fā)送給本地用戶的郵件。 POP3/IMAP郵件服務器:用戶幫助用戶讀取SMTP郵件服務器接收進來的郵件。
進階知識
- 什么是
JavaMailSender和JavaMailSenderImpl?JavaMailSender和JavaMailSenderImpl是Spring官方提供的集成郵件服務的接口和實現(xiàn)類,以簡單高效的設計著稱,目前是Java后端發(fā)送郵件和集成郵件服務的主流工具。 - 如何通過
JavaMailSenderImpl發(fā)送郵件? 非常簡單,直接在業(yè)務類注入JavaMailSenderImpl并調(diào)用send方法發(fā)送郵件。其中簡單郵件可以通過SimpleMailMessage來發(fā)送郵件,而復雜的郵件(例如添加附件)可以借助MimeMessageHelper來構建MimeMessage發(fā)送郵件。例如:
@Autowired
private JavaMailSenderImpl mailSender;
@Override
public void sendInlineAndAttachMail(String to, String subject, String content, String filePath,String rscPath, String rscId) {
logger.info("發(fā)送帶圖片郵件開始:{},{},{},{},{}", to, subject, content, rscPath, rscId);
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper;
try {
helper = new MimeMessageHelper(message, true);
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(content, true);
FileSystemResource file = new FileSystemResource(new File(filePath));
String fileName = file.getFilename();
helper.addAttachment(fileName, file);
FileSystemResource res = new FileSystemResource(new File(rscPath));
helper.addInline(rscId, res);//重復使用添加多個圖片
mailSender.send(message);
logger.info("發(fā)送帶圖片和附件郵件成功");
} catch (MessagingException e) {
logger.error("發(fā)送帶圖片和附件郵件失敗", e);
}
}
為什么JavaMailSenderImpl 能夠開箱即用 ? 所謂開箱即用其實就是基于官方內(nèi)置的自動配置,翻看源碼可知曉郵件自動配置類(MailSenderPropertiesConfiguration) 為上下文提供了郵件服務實例(JavaMailSenderImpl)。具體源碼如下:
@Configuration
@ConditionalOnProperty(prefix = "spring.mail", name = "host")
class MailSenderPropertiesConfiguration {
private final MailProperties properties;
MailSenderPropertiesConfiguration(MailProperties properties) {
this.properties = properties;
}
@Bean
@ConditionalOnMissingBean
public JavaMailSenderImpl mailSender() {
JavaMailSenderImpl sender = new JavaMailSenderImpl();
applyProperties(sender);
return sender;
}
其中MailProperties是關于郵件服務器的配置信息,具體源碼如下:
@ConfigurationProperties(prefix = "spring.mail")
public class MailProperties {
private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
private String host;
private Integer port;
private String username;
private String password;
private String protocol = "smtp";
private Charset defaultEncoding = DEFAULT_CHARSET;
private Map<String, String> properties = new HashMap<>();
}
Spring Boot 集成郵件發(fā)送主要分為以下三步:
加入依賴
pom.xml依賴spring-boot-starter-mail模塊:
<!--javax.mail 郵件發(fā)送-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
配置郵件
在配置文件 application.properties 中配置郵件的相關參數(shù),其中指定了郵件的協(xié)議、端口以及郵件賬戶和授權碼等。具體內(nèi)容如下:
#郵件配置 #SMTP服務器地址 spring.mail.host=smtp.qq.com #登陸賬號 spring.mail.username=2590742958@qq.com #注意這里不是郵箱密碼,而是SMTP授權密碼 spring.mail.password=lvlpxkujplqbdh spring.mail.default-encoding=UTF-8 #開啟加密驗證 spring.mail.properties.mail.smtp.ssl.enable=true #以下項不用改動 spring.mail.properties.mail.smtp.starttls.enable: true spring.mail.roperties.mail.smtp.starttls.required: true
編寫郵件發(fā)送service,contorller類等。
public class MailServiceImpl implements MailService {
private final Logger logger = LoggerFactory.getLogger(MailServiceImpl.class);
//使用@Value注入application.properties中指定的用戶名
@Value("${spring.mail.username}")
private String from;
@Autowired
//用于發(fā)送文件
private JavaMailSender mailSender;
@Override
public void sendAttachmentMail(String to, String subject, String content, String filePath) {
logger.info("發(fā)送帶附件郵件開始:{},{},{},{}", to, subject, content, filePath);
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper;
try {
helper = new MimeMessageHelper(message, true);
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(content, true);
FileSystemResource file = new FileSystemResource(new File(filePath));
String fileName = file.getFilename();
helper.addAttachment(fileName, file);//添加附件,可多次調(diào)用該方法添加多個附件
mailSender.send(message);
logger.info("發(fā)送帶附件郵件成功");
} catch (MessagingException e) {
logger.error("發(fā)送帶附件郵件失敗", e);
}
在發(fā)送郵件的同時,我們可以自定義參數(shù)從而生成豐富多彩的郵件,如下
public interface MailService {
/**
* 發(fā)送普通文本郵件
* @param to 收件人
* @param subject 主題
* @param content 內(nèi)容
*/
void sendSimpleMail(String to, String subject, String content);
/**
* 發(fā)送HTML郵件
* @param to 收件人
* @param subject 主題
* @param content 內(nèi)容(可以包含<html>等標簽)
*/
void sendHtmlMail(String to, String subject, String content);
/**
* 發(fā)送帶附件的郵件
* @param to 收件人
* @param subject 主題
* @param content 內(nèi)容
* @param filePath 附件路徑
*/
void sendAttachmentMail(String to, String subject, String content, String filePath);
/**
* 發(fā)送帶圖片的郵件
* @param to 收件人
* @param subject 主題
* @param content 文本
* @param rscPath 圖片路徑
* @param rscId 圖片ID,用于在<img>標簽中使用,從而顯示圖片
*/
void sendInlineResourceMail(String to, String subject, String content, String rscPath, String rscId);
/**
* 發(fā)送帶圖片的郵件
* @param to 收件人
* @param subject 主題
* @param content 文本
* @param rscPath 圖片路徑
* @param filePath 附件路徑
* @param rscId 圖片ID,用于在<img>標簽中使用,從而顯示圖片
*/
void sendInlineAndAttachMail(String to, String subject, String content,String filePath, String rscPath, String rscId);
}
測試郵件發(fā)送
編寫控制器層,這里使用的是Thymeleaf模板郵件,是常見的模板郵件,比如說我們注冊賬戶,登錄認證所收到的郵件即為模板郵件,特點就是內(nèi)容不變,只是一些特點信息比如說驗證碼、認證鏈接等是動態(tài)變化的。在模板頁面中,id是動態(tài)變化的,需要我們傳參設置,其實就是傳參后,將頁面解析為HTML字符串,作為我們郵件發(fā)送的主體內(nèi)容
@Controller
public class MailContorller {
@Autowired
private MailService mailService;
@Autowired
private TemplateEngine templateEngine;
@Resource
private UserService userService;
//這一步是獲取application.properties中設置的發(fā)件人郵箱地址
@Value("${spring.mail.username}")
private String Email;
@RequestMapping("/sendTemplate")
/** 指定模板發(fā)送郵件 */
public String sendTemplate(@RequestParam("Email") String Email, Model model) {
//具體的業(yè)務
User usermail= userService.retrieve(Email);
System.out.println(usermail);
if (usermail !=null){
//向Thymeleaf模板傳值,并解析成字符串
//通過Context構造模版中變量需要的值
Context context = new Context();
context.setVariable("id", "001");
String emailContent = templateEngine.process("emailTemplate", context);
mailService.sendHtmlMail(Email,"密碼找回驗證", emailContent);
return "Login";
}
else if(StringUtils.isEmpty(Email)){
model.addAttribute("yuoxiang","郵箱信息不能為空");
return "Login";
}
else {
model.addAttribute("yuoxiang","郵箱錯誤或者與綁定賬號不一致");
return "Login";
}
}
然后我們需要在template文件夾下創(chuàng)建emailTemplate.html,設計我們需求的模板樣式
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>密碼驗證</title>
</head>
<body>
<span style="color:#5ed02b;font-weight:600;font-size: 18px">您好,歡迎您的查看,這是一封驗證郵件,請根據(jù)下面系統(tǒng)找回的密碼完成登錄,感謝您的支持!</span><br>
</body>
</html>
調(diào)用發(fā)送復雜郵件方法后,根據(jù)獲取動態(tài)輸入的郵箱地址,成功后就可以在 QQ 郵箱中收到郵件:

總結:Springboot整合郵件發(fā)送的原理和實現(xiàn)

以上就是Springboot整合實現(xiàn)郵件發(fā)送的原理詳解的詳細內(nèi)容,更多關于Springboot郵件發(fā)送的資料請關注腳本之家其它相關文章!
相關文章
Java動態(tài)字節(jié)碼注入技術的實現(xiàn)
Java動態(tài)字節(jié)碼注入技術是一種在運行時修改Java字節(jié)碼的技術,本文主要介紹了Java動態(tài)字節(jié)碼注入技術的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下2023-08-08
SpringMVC中的@ControllerAdvice使用場景詳解
這篇文章主要介紹了SpringMVC中的@ControllerAdvice使用場景詳解,在Spring?MVC進行調(diào)用的過程中,會有很多的特殊的需求,比如全局異常,分頁信息和分頁搜索條件,請求時帶來返回時還得回顯頁面,需要的朋友可以參考下2024-01-01
mybatis(mybatis-plus)映射文件(XML文件)中特殊字符轉(zhuǎn)義的實現(xiàn)
XML 文件在解析時會將五種特殊字符進行轉(zhuǎn)義,本文主要介紹了mybatis(mybatis-plus)映射文件(XML文件)中特殊字符轉(zhuǎn)義的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下2023-12-12
Springboot整合FreeMarker的實現(xiàn)示例
本文主要介紹了Springboot整合FreeMarker的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-02-02
詳解Kotlin:forEach也能break和continue
這篇文章主要介紹了詳解Kotlin:forEach也能break和continue的相關資料,需要的朋友可以參考下2017-06-06

