• Java秒杀系统实战系列~开发通用的发送邮件服务


    摘要:

    本篇博文是“Java秒杀系统实战系列文章”的第九篇,在这篇文章中我们将继续完善秒杀系统中的核心处理逻辑,即“用户秒杀~抢单”的业务逻辑!本文我们将基于JavaMail服务,开发一个通用的发送邮件服务,用于发送邮件通知消息,并与上一篇章中已经实现的RabbitMQ异步发送消息的逻辑进行整合,彻底实现“用户秒杀成功后,异步发送邮件通知消息给到用户邮箱,告知用户尽快进行付款”的功能!

    内容:

    对于发送邮件服务,相信各位小伙伴并不陌生,本篇博文我们将开发一个通用的发送邮件服务,用于“用户秒杀成功之后异步发送邮件消息给到用户”。

    (1)同样的道理,首先我们需要加入发送邮件服务的依赖,其依赖的版本号跟SpringBoot的版本号一直,为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配置文件中加入“发送邮件服务”所需要的额外的支持配置信息:

    #发送邮件配置
    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=商品抢购成功
    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表中“邮箱字段值”对应的邮箱会受到一封邮件,如下图所示:

    好了,欢乐的撸码时光总是短暂的,本篇文章我们就介绍到这里了!下篇博文我们将继续我们的“秒杀系统实战”之旅!

    补充:

    1、目前,这一秒杀系统的整体构建与代码实战已经全部完成了,完整的源代码数据库地址可以来这里下载:gitee.com/steadyjack/… 记得Fork跟Star啊!!

    2、最后,不要忘记了关注一下Debug的技术微信公众号:

     

  • 相关阅读:
    mysql 大数据量求平均值
    mysql 大数据量求平均值
    dhcpd.conf(5)
    dhcpd.conf(5)
    学习记录(文章内容来自相关材料)
    分享一个ASP.NET 文件压缩解压类 C#
    服务降级
    distinct用法
    trim合理和谐
    小娱乐一下,fileInfo中的Name ,FullName的用法小BUG
  • 原文地址:https://www.cnblogs.com/SteadyJack/p/11268330.html
Copyright © 2020-2023  润新知