Spring Boot 仍然在狂速发展,才几个多月没有关注,现在看官网已经到 2.1.0.RELEASE 版本了。准备慢慢在写写 Spring Boot 相关的文章,本篇文章使用 Spring Boot 最新版本 2.1.0 进行开发。

发送邮件应该是网站的必备功能之一,什么注册验证,忘记密码或者是给用户发送营销信息。最早期的时候我们会使用 JavaMail 相关 api 来写发送邮件的相关代码,后来 Spring 推出了 JavaMailSender 更加简化了邮件发送的过程,在之后 Spring Boot 对此进行了封装就有了现在的 spring-boot-starter-mail ,本章文章的介绍主要来自于此包。

简单使用

1、pom 包配置

pom 包里面添加 spring-boot-starter-mail 包引用

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

2、在 application.properties 中添加邮箱配置

spring.mail.host=smtp.qiye.163.com //邮箱服务器地址
spring.mail.username=xxx@oo.com //用户名
spring.mail.password=xxyyooo //密码
spring.mail.default-encoding=UTF-8 mail.fromMail.addr=xxx@oo.com //以谁来发送邮件

3、编写 mailService,这里只提出实现类。

@Component
public class MailServiceImpl implements MailService{ private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired
private JavaMailSender mailSender; @Value("${mail.fromMail.addr}")
private String from; @Override
public void sendSimpleMail(String to, String subject, String content) {
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(from);
message.setTo(to);
message.setSubject(subject);
message.setText(content); try {
mailSender.send(message);
logger.info("简单邮件已经发送。");
} catch (Exception e) {
logger.error("发送简单邮件时发生异常!", e);
} }
}

4、编写 test 类进行测试

@RunWith(SpringRunner.class)
@SpringBootTest
public class MailServiceTest { @Autowired
private MailService MailService; @Test
public void testSimpleMail() throws Exception {
MailService.sendSimpleMail("ityouknow@126.com","test simple mail"," hello this is simple mail");
}
}

至此一个简单的文本发送就完成了。

加点料

但是在正常使用的过程中,我们通常在邮件中加入图片或者附件来丰富邮件的内容,下面讲介绍如何使用 Spring Boot 来发送丰富的邮件。

发送 html 格式邮件

其它都不变在 MailService 添加 sendHtmlMail 方法.

public void sendHtmlMail(String to, String subject, String content) {
MimeMessage message = mailSender.createMimeMessage(); try {
//true表示需要创建一个multipart message
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(content, true); mailSender.send(message);
logger.info("html邮件发送成功");
} catch (MessagingException e) {
logger.error("发送html邮件时发生异常!", e);
}
}

在测试类中构建 html 内容,测试发送

@Test
public void testHtmlMail() throws Exception {
String content="<html>\n" +
"<body>\n" +
" <h3>hello world ! 这是一封Html邮件!</h3>\n" +
"</body>\n" +
"</html>";
MailService.sendHtmlMail("ityouknow@126.com","test simple mail",content);
}

发送带附件的邮件

在 MailService 添加 sendAttachmentsMail 方法.

public void sendAttachmentsMail(String to, String subject, String content, String filePath){
MimeMessage message = mailSender.createMimeMessage(); try {
MimeMessageHelper 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 = filePath.substring(filePath.lastIndexOf(File.separator));
helper.addAttachment(fileName, file); mailSender.send(message);
logger.info("带附件的邮件已经发送。");
} catch (MessagingException e) {
logger.error("发送带附件的邮件时发生异常!", e);
}
}

添加多个附件可以使用多条 helper.addAttachment(fileName, file)

在测试类中添加测试方法

@Test
public void sendAttachmentsMail() {
String filePath="e:\\tmp\\application.log";
mailService.sendAttachmentsMail("ityouknow@126.com", "主题:带附件的邮件", "有附件,请查收!", filePath);
}

发送带静态资源的邮件

邮件中的静态资源一般就是指图片,在 MailService 添加 sendAttachmentsMail 方法.

public void sendInlineResourceMail(String to, String subject, String content, String rscPath, String rscId){
MimeMessage message = mailSender.createMimeMessage(); try {
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(content, true); FileSystemResource res = new FileSystemResource(new File(rscPath));
helper.addInline(rscId, res); mailSender.send(message);
logger.info("嵌入静态资源的邮件已经发送。");
} catch (MessagingException e) {
logger.error("发送嵌入静态资源的邮件时发生异常!", e);
}
}

在测试类中添加测试方法

@Test
public void sendInlineResourceMail() {
String rscId = "neo006";
String content="<html><body>这是有图片的邮件:<img src=\'cid:" + rscId + "\' ></body></html>";
String imgPath = "C:\\Users\\summer\\Pictures\\favicon.png"; mailService.sendInlineResourceMail("ityouknow@126.com", "主题:这是有图片的邮件", content, imgPath, rscId);
}

添加多个图片可以使用多条 <img src='cid:" + rscId + "' >helper.addInline(rscId, res) 来实现

到此所有的邮件发送服务已经完成了。

邮件系统

上面发送邮件的基础服务就这些了,但是如果我们要做成一个邮件系统的话还需要考虑以下几个问题:

邮件模板

我们会经常收到这样的邮件:

尊敬的neo用户:

          恭喜您注册成为xxx网的用户,,同时感谢您对xxx的关注与支持并欢迎您使用xx的产品与服务。
...

其中只有 neo 这个用户名在变化,其它邮件内容均不变,如果每次发送邮件都需要手动拼接的话会不够优雅,并且每次模板的修改都需要改动代码的话也很不方便,因此对于这类邮件需求,都建议做成邮件模板来处理。模板的本质很简单,就是在模板中替换变化的参数,转换为 html 字符串即可,这里以thymeleaf为例来演示。

1、pom 中导入 thymeleaf 的包

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

**2、在 resorces/templates 下创建 emailTemplate.html **

<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>Title</title>
</head>
<body>
您好,这是验证邮件,请点击下面的链接完成验证,<br/>
<a href="#" th:href="@{ http://www.ityouknow.com/neo/{id}(id=${id}) }">激活账号</a>
</body>
</html>

3、解析模板并发送

@Test
public void sendTemplateMail() {
//创建邮件正文
Context context = new Context();
context.setVariable("id", "006");
String emailContent = templateEngine.process("emailTemplate", context); mailService.sendHtmlMail("ityouknow@126.com","主题:这是模板邮件",emailContent);
}

发送失败

因为各种原因,总会有邮件发送失败的情况,比如:邮件发送过于频繁、网络异常等。在出现这种情况的时候,我们一般会考虑重新重试发送邮件,会分为以下几个步骤来实现:

  • 1、接收到发送邮件请求,首先记录请求并且入库。
  • 2、调用邮件发送接口发送邮件,并且将发送结果记录入库。
  • 3、启动定时系统扫描时间段内,未发送成功并且重试次数小于3次的邮件,进行再次发送

异步发送

很多时候邮件发送并不是我们主业务必须关注的结果,比如通知类、提醒类的业务可以允许延时或者失败。这个时候可以采用异步的方式来发送邮件,加快主交易执行速度,在实际项目中可以采用MQ发送邮件相关参数,监听到消息队列之后启动发送邮件。

可以参考前期文章:Spring Boot(八):RabbitMQ 详解 来实现。

文章内容已经升级到 Spring Boot 2.x

示例代码-github

示例代码-码云

参考:

spring boot 发送邮件

Spring Boot (十):邮件服务的更多相关文章

  1. spring boot(十)邮件服务

    springboot仍然在狂速发展,才五个多月没有关注,现在看官网已经到1.5.3.RELEASE版本了.准备慢慢在写写springboot相关的文章,本篇文章使用springboot最新版本1.5. ...

  2. Spring Boot :邮件服务

    简单使用 1.pom 包配置 pom 包里面添加 spring-boot-starter-mail 包引用 <dependencies> <dependency> <gr ...

  3. Spring Boot实现邮件服务,附常见邮箱的配置

    1. pom.xml文件中引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <art ...

  4. spring boot + activeMq 邮件服务

    引入依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>s ...

  5. spring boot和邮件服务

    1.运行环境 开发工具:intellij idea JDK版本:1.8 项目管理工具:Maven 4.0.0 2.GITHUB地址

  6. spring Boot(十九):使用Spring Boot Actuator监控应用

    spring Boot(十九):使用Spring Boot Actuator监控应用 微服务的特点决定了功能模块的部署是分布式的,大部分功能模块都是运行在不同的机器上,彼此通过服务调用进行交互,前后台 ...

  7. Spring Boot(十六):使用Jenkins部署Spring Boot

    Spring Boot(十六):使用Jenkins部署Spring Boot jenkins是devops神器,介绍如何安装和使用jenkins部署Spring Boot项目 jenkins搭建 部署 ...

  8. Spring Boot(十四):spring boot整合shiro-登录认证和权限管理

    Spring Boot(十四):spring boot整合shiro-登录认证和权限管理 使用Spring Boot集成Apache Shiro.安全应该是互联网公司的一道生命线,几乎任何的公司都会涉 ...

  9. Spring Boot(十二):spring boot如何测试打包部署

    Spring Boot(十二):spring boot如何测试打包部署 一.开发阶段 1,单元测试 在开发阶段的时候最重要的是单元测试了,springboot对单元测试的支持已经很完善了. (1)在p ...

  10. Spring Boot Admin实现服务健康预警

    Over View 上一篇文章主要介绍了Spring Boot Admin的概况以及我们如何在系统中引入和使用Spring Boot Admin,以此来帮助我们更加了解自己的系统,做到能快速发现.排查 ...

随机推荐

  1. yii2 注册一个新事件(trigger Event)

    有些时候我们需要在某个方法的中间注册一个新事件,确保某些业务的可拓展性. 下面我介绍一下注册一个新事件的方法: 第一步:需要的地方(比如控制器或模型)中定义一个事件常量(如:const EVENT_C ...

  2. UI框架

    一,框架构成:目录分别有bin,lib,page,report,test_case,(百度网盘) 1.bin>run.py 2.lib>HTMLTestRunner.py lib>l ...

  3. go、java or c艹 引用的本质

    在底层,引用变量由指针按照指针常量的方式实现 即一个指针常量,和一些解引用等的封装: 合到一起实现了指针这么一种形式. 用指针和引用编译到了汇编层面应该是一样的.

  4. today-Extension widget 扩展开发

    设置UI部分的展开和收起

  5. $.each()和$().each(),以及forEach()的用法

    1.forEach() 是JS遍历数组的方法 var arr=[1,2,3]; arr.forEach(function(val,index,arr){ // var 为数组中当前的值 // inde ...

  6. 反编译python打包的exe文件

    目录 1.前言 2.使用环境 3.还原过程 4.号外 5.exe文件和所用到的反编译工具 6.参考 7.去签名(补漏) 前言 拿到了利用驱动人生进行传播的病毒样本,发现是python打包成的exe文件 ...

  7. ARouter基础使用(一)

    一个用于帮助 Android App 进行组件化改造的框架 —— 支持模块间的路由.通信.解耦1.新建一个Android项目 "ARouterDemo"2.添加依赖和配置 andr ...

  8. Cloud Native 云化架构阅读笔记

    一• Cloud Native CloudNative是什么? Cloud Native翻译为云原生,是Matt Stine提出的一个概念,它是一个思想的集合,包括DevOps.持续交付(Contin ...

  9. Python练手例子(14)

    79.字符串排序. #python3.7 if __name__ == '__main__': str1 = input('Input string:\n') str2 = input('Input ...

  10. emWin监护仪界面设计,含uCOS-III和FreeRTOS两个版本

    第5期:监护仪界面设计 配套例子:V6-908_STemWin提高篇实验_监护仪界面设计(uCOS-III)V6-909_STemWin提高篇实验_监护仪界面设计(FreeRTOS) 例程下载地址:h ...