Java秒殺系統(tǒng)(九):開發(fā)通用的發(fā)送郵件服務(wù)
作者:
修羅debug
版權(quán)聲明:本文為博主原創(chuàng)文章,遵循 CC 4.0 by-sa 版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接和本聲明。
摘要:本篇博文是“Java秒殺系統(tǒng)實(shí)戰(zhàn)系列文章”的第九篇,在這篇文章中我們將繼續(xù)完善秒殺系統(tǒng)中的核心處理邏輯,即“用戶秒殺~搶單”的業(yè)務(wù)邏輯!本文我們將基于JavaMail服務(wù),開發(fā)一個(gè)通用的發(fā)送郵件服務(wù),用于發(fā)送郵件通知消息,并與上一篇章中已經(jīng)實(shí)現(xiàn)的RabbitMQ異步發(fā)送消息的邏輯進(jìn)行整合,徹底實(shí)現(xiàn)“用戶秒殺成功后,異步發(fā)送郵件通知消息給到用戶郵箱,告知用戶盡快進(jìn)行付款”的功能!
內(nèi)容:對(duì)于發(fā)送郵件服務(wù),相信各位小伙伴并不陌生,本篇博文我們將開發(fā)一個(gè)通用的發(fā)送郵件服務(wù),用于“用戶秒殺成功之后異步發(fā)送郵件消息給到用戶”。
(1) 同樣的道理,首先我們需要加入發(fā)送郵件服務(wù)的依賴,其依賴的版本號(hào)跟SpringBoot的版本號(hào)一直,為1.5.7.RELEASE,如下所示:
<!--mail-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
<version>${spring-boot.version}</version>
</dependency>
緊接著,我們需要在application.properties配置文件中加入“發(fā)送郵件服務(wù)”所需要的額外的支持配置信息:
#發(fā)送郵件配置
spring.mail.host=smtp.qq.com
spring.mail.username=1974544863@qq.com
spring.mail.password=cmtvsjvhonkjdaje
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
mail.send.from=1974544863@qq.com
mail.kill.item.success.subject=商品搶購(gòu)成功
mail.kill.item.success.content=您好,您已成功搶購(gòu)到商品: <strong style="color: red">%s</strong> ,復(fù)制該鏈接并在瀏覽器采用新的頁(yè)面打開,即可查看搶購(gòu)詳情:${system.domain.url}/kill/record/detail/%s,并請(qǐng)您在1個(gè)小時(shí)內(nèi)完成訂單的支付,超時(shí)將失效該訂單哦!祝你生活愉快!
在本秒殺系統(tǒng)中,發(fā)送郵件的服務(wù)我們是采用 QQ郵箱 作為主郵箱賬號(hào),相應(yīng)的SMTP服務(wù)器也是采用QQ郵箱的!其中,spring.mail.password 指的是在QQ郵箱后臺(tái)開通POP3/SMTP服務(wù) 時(shí)騰訊官方給的“密鑰”(授權(quán)碼),在這里,Debug就貢獻(xiàn)了上面那個(gè)密鑰~授權(quán)碼 給各位使用了,而真正在企業(yè)生產(chǎn)環(huán)境中,其實(shí)是需要去申請(qǐng)一個(gè)主郵箱賬號(hào)的,至于如何申請(qǐng),在這里就不贅述了!
(2) 接下來(lái),我們就可以大顯伸手一番了!我們?cè)贛ailService中開發(fā)了兩種發(fā)送郵件的功能,一種發(fā)送簡(jiǎn)單文本的功能(即純文字的、很死板、高冷風(fēng)的那種),另一種是發(fā)送帶HTML標(biāo)簽的花哨文本的功能(即帶樣式的、比較俏皮的、有溫度的那種),如下所示:
//通用的發(fā)送郵件服務(wù)
@Service
@EnableAsync
public class MailService {
private static final Logger log= LoggerFactory.getLogger(MailService.class);
@Autowired
private JavaMailSender mailSender;
@Autowired
private Environment env;
//發(fā)送簡(jiǎn)單文本文件
@Async
public void sendSimpleEmail(final MailDto dto){
try {
SimpleMailMessage message=new SimpleMailMessage();
message.setFrom(env.getProperty("mail.send.from"));
message.setTo(dto.getTos());
message.setSubject(dto.getSubject());
message.setText(dto.getContent());
mailSender.send(message);
log.info("發(fā)送簡(jiǎn)單文本文件-發(fā)送成功!");
}catch (Exception e){
log.error("發(fā)送簡(jiǎn)單文本文件-發(fā)生異常: ",e.fillInStackTrace());
}
}
//發(fā)送花哨郵件
@Async
public void sendHTMLMail(final MailDto dto){
try {
MimeMessage message=mailSender.createMimeMessage();
MimeMessageHelper messageHelper=new MimeMessageHelper(message,true,"utf-8");
messageHelper.setFrom(env.getProperty("mail.send.from"));
messageHelper.setTo(dto.getTos());
messageHelper.setSubject(dto.getSubject());
messageHelper.setText(dto.getContent(),true);
mailSender.send(message);
log.info("發(fā)送花哨郵件-發(fā)送成功!");
}catch (Exception e){
log.error("發(fā)送花哨郵件-發(fā)生異常: ",e.fillInStackTrace());
}
}
}
其中,MailDto類主要統(tǒng)一封裝了在發(fā)送郵件時(shí)所需要的字段信息,比如接收人、郵件標(biāo)題、郵件內(nèi)容等等(提現(xiàn)了面向?qū)ο蟮闹匾匦裕?!其源代碼如下所示:
/**統(tǒng)一封裝了在發(fā)送郵件時(shí)所需要的字段信息
* @Author:debug (SteadyJack)
* @Date: 2019/6/22 10:11
**/
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class MailDto implements Serializable{
//郵件主題
private String subject;
//郵件內(nèi)容
private String content;
//接收人
private String[] tos;
}
(3) 最后是在“RabbitMQ通用的消息接收服務(wù)類” RabbitReceiverService 的接收消息邏輯中整合進(jìn)“發(fā)送郵件服務(wù)”的邏輯,如下所示:
@Autowired
private MailService mailService;
@Autowired
private Environment env;
/**
* 秒殺異步郵件通知-接收消息
*/
@RabbitListener(queues = {"${mq.kill.item.success.email.queue}"},containerFactory = "singleListenerContainer")
public void consumeEmailMsg(KillSuccessUserInfo info){
try {
log.info("秒殺異步郵件通知-接收消息:{}",info);
//TODO:真正的發(fā)送郵件....
//簡(jiǎn)單文本
//MailDto dto=new MailDto(env.getProperty("mail.kill.item.success.subject"),"這是測(cè)試內(nèi)容",new String[]{info.getEmail()});
//mailService.sendSimpleEmail(dto);
//花哨文本
final String content=String.format(env.getProperty("mail.kill.item.success.content"),info.getItemName(),info.getCode());
MailDto dto=new MailDto(env.getProperty("mail.kill.item.success.subject"),content,new String[]{info.getEmail()});
mailService.sendHTMLMail(dto);
}catch (Exception e){
log.error("秒殺異步郵件通知-接收消息-發(fā)生異常:",e.fillInStackTrace());
}
}
(4) 至此,關(guān)于通用的發(fā)送郵件服務(wù)的代碼實(shí)戰(zhàn),我們就介紹到這里了,接下來(lái)我們進(jìn)入測(cè)試環(huán)節(jié)。點(diǎn)擊“搶購(gòu)”,如果用戶秒殺成功,系統(tǒng)后端會(huì)在數(shù)據(jù)庫(kù)錄入一筆秒殺成功后的訂單,同時(shí)user表中“郵箱字段值”對(duì)應(yīng)的郵箱會(huì)受到一封郵件,如下圖所示:
好了,歡樂的擼碼時(shí)光總是短暫的,本篇文章我們就介紹到這里了!下篇博文我們將繼續(xù)我們的“秒殺系統(tǒng)實(shí)戰(zhàn)”之旅!
補(bǔ)充:
1、目前,這一秒殺系統(tǒng)的整體構(gòu)建與代碼實(shí)戰(zhàn)已經(jīng)全部完成了,該秒殺系統(tǒng)對(duì)應(yīng)的視頻教程的鏈接地址為:https://www.fightjava.com/web/index/course/detail/6,可以點(diǎn)擊鏈接進(jìn)行試看以及學(xué)習(xí),實(shí)戰(zhàn)期間有任何問題都可以留言或者與Debug聯(lián)系、交流!
2、另外,Debug也開源了該秒殺系統(tǒng)對(duì)應(yīng)的完整的源代碼以及數(shù)據(jù)庫(kù),其地址可以來(lái)這里下載:https://gitee.com/steadyjack/SpringBoot-SecondKill 記得Fork跟Star?。。?!
3、最后,不要忘記了關(guān)注一下Debug的技術(shù)微信公眾號(hào)