整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

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

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
 publicvoid 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=newMimeMessageHelper(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(KillSuccessUserInfoinfo){
 try {
 log.info("秒杀异步邮件通知-接收消息:{}",info);
 //TODO:真正的发送邮件....
 //简单文本
 //MailDto dto=newMailDto(env.getProperty("mail.kill.item.success.subject"),"这是测试内容",new String[]{info.getEmail()});
 //mailService.sendSimpleEmail(dto);
 //花哨文本
 finalString content=String.format(env.getProperty("mail.kill.item.success.content"),info.getItemName(),info.getCode());
 MailDto dto=newMailDto(env.getProperty("mail.kill.item.success.subject"),content,newString[]{info.getEmail()});
 mailService.sendHTMLMail(dto);
 }catch(Exception e){
 log.error("秒杀异步邮件通知-接收消息-发生异常:",e.fillInStackTrace());
 }
}

(4)至此,关于通用的发送邮件服务的代码实战,我们就介绍到这里了,接下来我们进入测试环节。点击“抢购”,如果用户秒杀成功,系统后端会在数据库录入一笔秒杀成功后的订单,同时user表中“邮箱字段值”对应的邮箱会受到一封邮件,如下图所示:

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

**

* 发送邮件

* @param protocol:邮件传输协议,可空

* @param host:邮件服务器

* @param port:端口,可空

* @param auth:是否验证身份

* @param username:用户

* @param password:密码

* @param enableSsl:是否启用设置SSL加密

* @param fromEmailAddress:发件人

* @param toEmailAddress:收件人

* @param ccEmailAddress:抄送人,可空

* @param bccEmailAddress:密送人,可空

* @param subject:邮件主题

* @param content:邮件内容

* @param contentType:内容格式,可空,HTML格式:text/html

* @param containAttachment:是否包含附件

* @param attachmentPath:附件路径,可空

* @return

*/

public static Map<String, String> sendEmail(String protocol, String host,

String port, boolean auth, final String username,

final String password, boolean enableSsl, String fromEmailAddress,

String[] toEmailAddress, String[] ccEmailAddress,

String[] bccEmailAddress, String subject, String content,

String contentType, boolean containAttachment, String attachmentPath) {

Map<String, String> result=new HashMap<String, String>();

String returnCode="1"; //返回结果,0异常,1成功

String returnMsg=""; //返回消息

try {

// 创建属性对象

Properties properties=new Properties();

// 设置邮件传输采用的协议

if(null !=protocol && !"".equals(protocol)){

properties.setProperty("mail.transport.protocol", protocol);

}

在实际项目中,经常需要用到邮件通知功能。比如,用户通过邮件注册,通过邮件找回密码等;又比如通过邮件发送系统情况,通过邮件发送报表信息等等,实际应用场景很多。这篇文章,就教大家通过springboot快速的实现一个发送邮件的功能。

引入依赖

在springboot项目中,引入如下依赖:

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

配置文件

在springboot项目中引入依赖之后,即可在其配置文件中配置邮箱的参数:

application.properties

不同的邮箱,host的配置不一样。如果是其它邮箱,搜索下即可找到。

username为邮箱账号,password为邮箱的授权码(不是密码,需要在邮箱的设置页面中开启smtp)。

注入JavaMailSender实例

邮箱参数配置完之后,即可直接注入JavaMailSender实例。

@Autowired
private JavaMailSender javaMailSender;

发送普通邮件

普通邮件,没有样式。实现起来最容易:

@Test
public void testSend() throws MessagingException {
 SimpleMailMessage message=new SimpleMailMessage();
 message.setFrom("发送者邮箱地址");
 message.setTo("接受者邮箱地址");
 message.setSubject("这是标题");
 message.setText("这是内容");
 javaMailSender.send(message);
}

From需要和配置文件中的username一致,否则会报错。

To为邮件接收者;

Subject为邮件的标题;

Text为邮件的内容。

运行方法,即可收到邮件:

发送HTML邮件

很多时候,我们需要邮件带有美观的样式。这时候,可以使用HTML的样式。我们需要使用javaMailSender的createMimeMessage方法,构建一个MimeMessage,然后使用MimeMessage实例创建出MimeMessageHelper。如下:

@Test
public void testSend() throws MessagingException {
 MimeMessage mimeMessage=javaMailSender.createMimeMessage();
 MimeMessageHelper messageHelper=new MimeMessageHelper(mimeMessage);
 messageHelper.setSubject("标题");
 messageHelper.setFrom("发送者邮箱地址");
 messageHelper.setTo("接受者邮箱地址");
 messageHelper.setText("<h1>标题</h1><br/><p>这是内容</p>", true);
 javaMailSender.send(messageHelper.getMimeMessage());
}

这里需要注意的是,setText的时候需要传一个布尔值进去,表名需要使用HTML样式。

运行方法查看结果:

可以看到,h1的样式已经出来了。

总结

本文讲解了如何在springboot中快速的发邮件。介绍了两种发送邮件的方式:1、普通模式;2、HTML模式。其实还支持多种丰富的模式,比如模板引擎等,这里就不讲解了,其实使用起来大同小异。