天天看點

Java秒殺系統實戰系列~開發通用的發送郵件服務

摘要:

本篇博文是“

Java秒殺系統實戰

系列文章”的第九篇,在這篇文章中我們将繼續完善秒殺系統中的核心處理邏輯,即“使用者秒殺~搶單”的業務邏輯!本文我們将基于JavaMail服務,開發一個通用的發送郵件服務,用于發送郵件通知消息,并與上一篇章中已經實作的RabbitMQ異步發送消息的邏輯進行整合,徹底實作“使用者秒殺成功後,異步發送郵件通知消息給到使用者郵箱,告知使用者盡快進行付款”的功能!

内容:

對于發送郵件服務,相信各位小夥伴并不陌生,本篇博文我們将開發一個通用的發送郵件服務,用于“使用者秒殺成功之後異步發送郵件消息給到使用者”。

(1)同樣的道理,首先我們需要加入發送郵件服務的依賴,其依賴的版本号跟SpringBoot的版本号一直,為1.5.7.RELEASE,如下所示:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
    <version>${spring-boot.version}</version>
</dependency>           

緊接着,我們需要在application.properties配置檔案中加入“發送郵件服務”所需要的額外的支援配置資訊:

#發送郵件配置
spring.mail.host=smtp.qq.com
[email protected]
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

[email protected]

mail.kill.item.success.subject=商品搶購成功
mail.kill.item.success.content=您好,您已成功搶購到商品: <strong style="color: red">%s</strong> ,複制該連結并在浏覽器采用新的頁面打開,即可檢視搶購詳情:${system.domain.url}/kill/record/detail/%s,并請您在1個小時内完成訂單的支付,逾時将失效該訂單哦!祝你生活愉快!           

在本秒殺系統中,發送郵件的服務我們是采用 QQ郵箱 作為主郵箱賬号,相應的SMTP伺服器也是采用QQ郵箱的!其中,spring.mail.password 指的是在QQ郵箱背景開通POP3/SMTP服務 時騰訊官方給的“密鑰”(授權碼),在這裡,Debug就貢獻了上面那個密鑰~授權碼 給各位使用了,而真正在企業生産環境中,其實是需要去申請一個主郵箱賬号的,至于如何申請,在這裡就不贅述了!

(2)接下來,我們就可以大顯伸手一番了!我們在MailService中開發了兩種發送郵件的功能,一種發送簡單文本的功能(即純文字的、很死闆、高冷風的那種),另一種是發送帶HTML标簽的花哨文本的功能(即帶樣式的、比較俏皮的、有溫度的那種),如下所示:

//通用的發送郵件服務
@Service
@EnableAsync
public class MailService {
    private static final Logger log= LoggerFactory.getLogger(MailService.class);

    @Autowired
    private JavaMailSender mailSender;

    @Autowired
    private Environment env;

    //發送簡單文本檔案
    @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("發送簡單文本檔案-發送成功!");
        }catch (Exception e){
            log.error("發送簡單文本檔案-發生異常: ",e.fillInStackTrace());
        }
    }

    //發送花哨郵件
    @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("發送花哨郵件-發送成功!");
        }catch (Exception e){
            log.error("發送花哨郵件-發生異常: ",e.fillInStackTrace());
        }
    }
}           

其中,MailDto類主要統一封裝了在發送郵件時所需要的字段資訊,比如接收人、郵件标題、郵件内容等等(提現了面向對象的重要特性)!其源代碼如下所示:

/**統一封裝了在發送郵件時所需要的字段資訊
 * @Author:debug (SteadyJack)
 * @Date: 2019/6/22 10:11
 **/
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class MailDto implements Serializable{
    //郵件主題
    private String subject;
    //郵件内容
    private String content;
    //接收人
    private String[] tos;
}           

(3)最後是在“RabbitMQ通用的消息接收服務類” RabbitReceiverService 的接收消息邏輯中整合進“發送郵件服務”的邏輯,如下所示:

@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:真正的發送郵件....
        //簡單文本
        //MailDto dto=new MailDto(env.getProperty("mail.kill.item.success.subject"),"這是測試内容",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("秒殺異步郵件通知-接收消息-發生異常:",e.fillInStackTrace());
    }
}           

(4)至此,關于通用的發送郵件服務的代碼實戰,我們就介紹到這裡了,接下來我們進入測試環節。點選“搶購”,如果使用者秒殺成功,系統後端會在資料庫錄入一筆秒殺成功後的訂單,同時user表中“郵箱字段值”對應的郵箱會受到一封郵件,如下圖所示:

Java秒殺系統實戰系列~開發通用的發送郵件服務

好了,歡樂的撸碼時光總是短暫的,本篇文章我們就介紹到這裡了!下篇博文我們将繼續我們的“秒殺系統實戰”之旅!

補充:

1、由于相應的部落格的更新可能并不會很快,故而如果有想要快速入門以及實戰整套系統的,可以閱讀:

Java商城秒殺系統的設計與實戰視訊教程(SpringBoot版)

2、目前,這一秒殺系統的整體建構與代碼實戰已經全部完成了,完整的源代碼資料庫位址可以來這裡下載下傳:

https://gitee.com/steadyjack/SpringBoot-SecondKill