最早我们发邮件的时候是使用 JavaMail 来发送邮件,而在 Spring Boot 中, Spring Boot 帮我们将 JavaMail 封装好了,是可以直接拿来使用的。

1. 依赖文件 pom.xml

代码清单:spring-boot-mail/pom.xml


  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-mail</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework.boot</groupId>
  8. <artifactId>spring-boot-starter-thymeleaf</artifactId>
  9. </dependency>
  10. <dependency>
  11. <groupId>org.springframework.boot</groupId>
  12. <artifactId>spring-boot-starter-test</artifactId>
  13. <scope>test</scope>
  14. </dependency>
  15. </dependencies>
  • spring-boot-starter-thymeleaf 引入这个模版引擎是因为我们在发送邮件的时候,各种格式使用 HTML 的方式更容易实现,同样我们也可以使用 freeMark , Spring Boot 同样为我们提供了依赖包。

2. 配置文件 application.yml

代码清单:


  1. server:
  2. port: 8080
  3. spring:
  4. application:
  5. name: spring-boot-mail
  6. mail:
  7. host: smtp.qq.com
  8. username: 136736247
  9. password: xxxxxx
  10. default-encoding: UTF-8
  11. fromAddr: 136736247@qq.com
  12. nickName: inwsy

这里我使用 QQ 邮箱作为邮件的发送方,其中的 password 并不是我们的 QQ 密码,这个密码需要我们在 QQ 邮箱的设置里面自己申请的。如下图:

其中的 spring.mail.fromAddrspring.mail.nickName 这两个配置是我自己配置的,并不是官方的配置,后续我会在代码中读这两个配置项。

3. 简易邮件发送

3.1 实现类

代码清单:spring-boot-mail/src/main/java/com/springboot/springbootmail/service/impl/MailServiceImpl.java


  1. @Service
  2. public class MailServiceImpl implements MailService {
  3. private final Logger logger = LoggerFactory.getLogger(this.getClass());
  4. @Autowired
  5. private JavaMailSender javaMailSender;
  6. @Value("${spring.mail.fromAddr}")
  7. private String from;
  8. @Value("${spring.mail.nickName}")
  9. private String nickName;
  10. @Override
  11. public void sendSimpleEmail(String to, String subject, String content) {
  12. SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
  13. simpleMailMessage.setFrom(nickName + "<" + from + ">");
  14. simpleMailMessage.setTo(to);
  15. simpleMailMessage.setSubject(subject);
  16. simpleMailMessage.setText(content);
  17. try{
  18. javaMailSender.send(simpleMailMessage);
  19. logger.info("简易邮件发送成功");
  20. } catch(Exception e) {
  21. logger.error("简易邮件发送异常", e);
  22. }
  23. }
  24. }

3.2 测试类

代码清单:spring-boot-mail/src/test/java/com/springboot/springbootmail/SpringBootMailApplicationTests.java


  1. @Autowired
  2. MailService mailService;
  3. @Test
  4. public void sendSimpleEmail() {
  5. mailService.sendSimpleEmail("inwsy@hotmail.com", "测试邮件题目", "测试邮件内容");
  6. }

这里邮件发送至本人的 Hotmail 邮箱。

4. 发送 HTML 格式的邮件

4.1 实现类

代码清单:spring-boot-mail/src/main/java/com/springboot/springbootmail/service/impl/MailServiceImpl.java


  1. @Override
  2. public void sendHTMLEmail(String to, String subject, String content) {
  3. MimeMessage message = javaMailSender.createMimeMessage();
  4. try {
  5. MimeMessageHelper messageHelper = new MimeMessageHelper(message, true);
  6. messageHelper.setFrom(new InternetAddress(from, nickName, "UTF-8"));
  7. messageHelper.setTo(to);
  8. messageHelper.setSubject(subject);
  9. messageHelper.setText(content, true);
  10. javaMailSender.send(message);
  11. logger.info("HTML 模版邮件发送成功");
  12. } catch (MessagingException e) {
  13. logger.error("HTML 模版邮件发送失败", e);
  14. } catch (UnsupportedEncodingException e) {
  15. logger.error("收件地址编码异常", e);
  16. }
  17. }

4.2 页面模版

代码清单:spring-boot-mail/src/main/resources/templates/email.html


  1. <!DOCTYPE html>
  2. <html lang="zh" xmlns:th="http://www.thymeleaf.org">
  3. <head>
  4. <meta charset="UTF-8"/>
  5. <title>邮件模版</title>
  6. </head>
  7. <body>
  8. 这是邮件模版生成的邮件,可以点击链接查看详情。
  9. <a href="#" th:href="@{ http://www.geekdigging.com/ }">查看详情。</a>
  10. 当前的Code为:<span th:text="${code}"></span>
  11. </body>
  12. </html>

这里添加了动态内容 code ,在日常的开发中,我们使用发送验证码,动态生成内容是很有必要的。

4.3 测试类

代码清单:spring-boot-mail/src/test/java/com/springboot/springbootmail/SpringBootMailApplicationTests.java


  1. @Test
  2. public void sendHTMLTemplateMail() {
  3. Context context = new Context();
  4. context.setVariable("code", "123456");
  5. String emailHTMLContent = templateEngine.process("email", context);
  6. mailService.sendHTMLEmail("inwsy@hotmail.com", "测试 HTML 模版邮件", emailHTMLContent);
  7. }

5. 发送带附件的邮件

5.1 实现类

代码清单:spring-boot-mail/src/main/java/com/springboot/springbootmail/service/impl/MailServiceImpl.java


  1. @Override
  2. public void sendAttachmentsMail(String to, String subject, String content, String fileName, String filePath) {
  3. MimeMessage message = javaMailSender.createMimeMessage();
  4. try {
  5. MimeMessageHelper messageHelper = new MimeMessageHelper(message, true);
  6. messageHelper.setFrom(new InternetAddress(from, nickName, "UTF-8"));
  7. messageHelper.setTo(to);
  8. messageHelper.setSubject(subject);
  9. messageHelper.setText(content, true);
  10. FileSystemResource file = new FileSystemResource(new File(filePath));
  11. messageHelper.addAttachment(fileName, file);
  12. javaMailSender.send(message);
  13. logger.info("带附件邮件发送成功");
  14. } catch (MessagingException e) {
  15. logger.error("带附件邮件发送失败", e);
  16. } catch (UnsupportedEncodingException e) {
  17. logger.error("收件地址编码异常", e);
  18. }
  19. }

注意: 如果需要发送多个附件,写多个 messageHelper.addAttachment(fileName, file); 即可。

5.2 测试类

代码清单:spring-boot-mail/src/test/java/com/springboot/springbootmail/SpringBootMailApplicationTests.java


  1. @Test
  2. public void sendAttachmentsMail() {
  3. String fileName = "图片.jpg";
  4. String filePath = "C:\\Users\\inwsy\\Downloads\\0370279582fe3e2a8012060c896a5dd.jpg";
  5. mailService.sendAttachmentsMail("inwsy@hotmail.com", "测试带附件的邮件", "详细请查阅附件", fileName, filePath);
  6. }

6. 小结

在实际的开发过程中,邮件发送失败是一件比较经常出现的事情,比如:网络堵塞、对方拒收等情况,一般在邮件系统的设计中,可以先将要发送的数据写入数据中,等发送完成后再修改标记位,再增加一个保障机制,例如增加一个定时任务,将一段时间内,发送失败并重试次数小于一定阀值的内容再次进行发送,如果邮件系统的压力过大,可以选择使用异步的方式来进行发送,比如使用消息队列进行承压。

7. 示例代码

示例代码-Github

示例代码-Gitee

7. 参考

http://www.ityouknow.com/springboot/2017/05/06/spring-boot-mail.html

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

  1. Spring学习(十二)-----Spring @PostConstruct和@PreDestroy实例

    实现 初始化方法和销毁方法3种方式: 实现标识接口 InitializingBean,DisposableBean(不推荐使用,耦合性太高) 设置bean属性 Init-method destroy- ...

  2. Spring学习(十二)-----Spring Bean init-method 和 destroy-method实例

    实现 初始化方法和销毁方法3种方式: 实现标识接口 InitializingBean,DisposableBean(不推荐使用,耦合性太高) 设置bean属性 Init-method destroy- ...

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

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

  4. Spring Boot 2.X(十三):邮件服务

    前言 邮件服务在开发中非常常见,比如用邮件注册账号.邮件作为找回密码的途径.用于订阅内容定期邮件推送等等,下面就简单的介绍下邮件实现方式. 准备 一个用于发送的邮箱,本文是用腾讯的域名邮箱,可以自己搞 ...

  5. Spring Cloud(二):Eureka 服务注册中心

    前言 服务治理 随着业务的发展,微服务应用也随之增加,这些服务的管理和治理会越来越难,并且集群规模.服务位置.服务命名都会发生变化,手动维护的方式极易发生错误或是命名冲突等问题.而服务治理正是为了解决 ...

  6. Java进阶(五十二)利用LOG4J生成服务日志

    Java进阶(五十二)利用LOG4J生成服务日志 前言 由于论文写作需求,需要进行流程挖掘.前提是需要有真实的事件日志数据.真实的事件日志数据可以用来发现.监控和提升业务流程. 为了获得真实的事件日志 ...

  7. Spring Boot 2.x (十八):邮件服务一文打尽

    前景介绍 在日常的工作中,我们经常会用到邮件服务,比如发送验证码,找回密码确认,注册时邮件验证等,所以今天在这里进行邮件服务的一些操作. 大致思路 我们要做的其实就是把Java程序作为一个客户端,然后 ...

  8. Spring Boot2 系列教程(三十二)Spring Boot 整合 Shiro

    在 Spring Boot 中做权限管理,一般来说,主流的方案是 Spring Security ,但是,仅仅从技术角度来说,也可以使用 Shiro. 今天松哥就来和大家聊聊 Spring Boot ...

  9. spring boot(十五)spring boot+thymeleaf+jpa增删改查示例

    快速上手 配置文件 pom包配置 pom包里面添加jpa和thymeleaf的相关包引用 <dependency> <groupId>org.springframework.b ...

  10. Spring Boot系列二 Spring @Async异步线程池用法总结

    1. TaskExecutor Spring异步线程池的接口类,其实质是java.util.concurrent.Executor Spring 已经实现的异常线程池: 1. SimpleAsyncT ...

随机推荐

  1. Go组件学习——手写连接池并没有那么简单

    1.背景 前段时间在看gorm,发现gorm是复用database/sql的连接池. 于是翻了下database/sql的数据库连接池的代码实现,看完代码,好像也不是很复杂,但是总觉得理解不够深刻,于 ...

  2. c++拷贝构造函数引用传参

    看一道C++面试题: 给出下述代码,分析编译运行的结果,并提供3个选项: A.编译错误  B.编译成功,运行时程序崩溃  C.编译运行正常,输出10 class A { private: int va ...

  3. eclipse中SpringBoot的maven项目出现无法解析父类的解决办法

    在eclipse中建立SpringBoot的maven项目时,继承父类,添加如下代码: <parent> <groupId>org.springframework.boot&l ...

  4. Day004课程内容

    本节主要内容: 1.列表List L = [1,'哈哈哈','吼吼',[1,8,0],('"我“,"叫","元","组"),”ab ...

  5. FaceBook快捷登入

    关于集成FaceBook快捷登入,我上回做了个最简单的版本,所有Web端通用,在这边共享下,有更好的解决方案的,麻烦评论留个地址,有不妥之处请指正. 首先,我们先加载Facebook的Js windo ...

  6. 在C#一个程序中,将一个窗体中的数据传送到另一个窗体

    使用多个窗体搭建的程序,需要用到窗体间的数据传递,常用两种方法: 方法一 1,进入子窗体的Designer.cs,将子窗体中的私有控件控件定义为public 2.在主窗口程序Form1.cs中将子窗口 ...

  7. 初学FPGA图像处理,开发板选择建议

    我用的是ZYNQ7010的开发板,纯粹是入门学习,对于初学者,使用较多的xlinx入门级的开发板一般是zynq7000系列,淘宝上买的较好的是黑金和米联科,我买的就是黑金的,个人觉得教程很少,学习资料 ...

  8. mybatis #号与$号的区别

    区别: 在sql中当传入的参数是字符型,则用#号会带上单引号,不会引起sql注入: 在sql中当传入的参数是字符型,则用$号不会带上单引号,会引起sql注入: 使用范围: 当传入的参数用于查询条件,尽 ...

  9. JAVA WEB中的Servlet过滤器

    实现一个Servlet过滤器,可以对用户登录情况进行控制.要求如下: 1)访问路径是admin下的资源,需要登录,如果用户没有登录,自动转向用户登录页面.用户登录成功后,再次访问admin下的资源不需 ...

  10. Prometheus Operator 监控Kubernetes

    Prometheus Operator 监控Kubernetes 1. Prometheus的基本架构 ​ Prometheus是一个开源的完整监控解决方案,涵盖数据采集.查询.告警.展示整个监控流程 ...