当前位置:   article > 正文

SpringBoot整合发送邮件的四种方式_springboot整合mimemessage

springboot整合mimemessage

目录

一、开启SMTP服务

二、搭建SpringBoot项目

三、发送邮件



    邮件发送是一个非常非常常见的功能,注册时的身份认证、 重要通知发送等都会用到邮件发送。Sun公司提供了JavaMail用来实现邮件发送,但是配置烦琐。Spring 中提供了JavaMailSender用来简化邮件配置。Spring Boot 则提供了 MailSenderAutoConfiguration 对邮件的发送做了进一步简化现在我们就来学习在Spring Boot中如何发送邮件。
    本文将介绍四种类型邮件的发送方式:简单文本邮件、带附件邮件、邮件正文带图片、使用Themeleaf构建邮件模板。

一、开启SMTP服务

如果想要发送邮件,我们需要开启SMTP服务,这里以QQ邮箱为例:

设置--账户

 拉到下面,找到账户安全,如下图所示,需要做的就是开启SMTP服务,然后生成授权码,代码中发邮件的时候需要用到授权码:

二、搭建SpringBoot项目

完整的项目已上传到gitee:https://gitee.com/tt1996/AllOpenDemo.git

首先是pom.xml文件,重点是需要添加,spring-boot-starter-mail依赖,完整的pom文件如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6. <parent>
  7. <groupId>org.springframework.boot</groupId>
  8. <artifactId>spring-boot-starter-parent</artifactId>
  9. <version>2.1.7.RELEASE</version>
  10. <relativePath/> <!-- lookup parent from repository -->
  11. </parent>
  12. <groupId>org.example</groupId>
  13. <artifactId>springboot_mail</artifactId>
  14. <version>1.0-SNAPSHOT</version>
  15. <properties>
  16. <java.version>1.8</java.version>
  17. <knife4j.version>2.0.4</knife4j.version>
  18. <lombok.version>1.18.10</lombok.version>
  19. <hutool.version>5.2.5</hutool.version>
  20. <mybatis-plus.version>3.0.6</mybatis-plus.version>
  21. </properties>
  22. <dependencies>
  23. <!--web依赖-->
  24. <dependency>
  25. <groupId>org.springframework.boot</groupId>
  26. <artifactId>spring-boot-starter-web</artifactId>
  27. </dependency>
  28. <dependency>
  29. <groupId>org.apache.commons</groupId>
  30. <artifactId>commons-pool2</artifactId>
  31. </dependency>
  32. <!-- Mail -->
  33. <dependency>
  34. <groupId>org.springframework.boot</groupId>
  35. <artifactId>spring-boot-starter-mail</artifactId>
  36. </dependency>
  37. <!--junit依赖-->
  38. <!-- <dependency>-->
  39. <!-- <groupId>junit</groupId>-->
  40. <!-- <artifactId>junit</artifactId>-->
  41. <!-- <version>4.8.2</version>-->
  42. <!-- <scope>test</scope>-->
  43. <!-- </dependency>-->
  44. <!--spring test测试依赖-->
  45. <dependency>
  46. <groupId>org.springframework.boot</groupId>
  47. <artifactId>spring-boot-starter-test</artifactId>
  48. </dependency>
  49. <dependency>
  50. <groupId>org.apache.commons</groupId>
  51. <artifactId>commons-configuration2</artifactId>
  52. <version>2.3</version>
  53. </dependency>
  54. <dependency>
  55. <groupId>org.springframework.boot</groupId>
  56. <artifactId>spring-boot-starter-thymeleaf</artifactId>
  57. </dependency>
  58. </dependencies>
  59. </project>

        然后是application.yml配置文件。其中用户名username和口令一定要换成你自己的,口令就是第一步开启SMTP服务发给你的授权码。

       关于配置的含义,注释已经详细做了介绍。完整配置如下:

  1. server:
  2. port: 8086
  3. #邮件设置
  4. #spring.mail.host=smtp.exmail.qq.com
  5. #暂时改为个人邮箱smtp服务器进行测试
  6. spring:
  7. mail:
  8. #坑爹的地方:host 通道个人邮箱和企业邮箱通道不同。163的个人邮箱:smtp.163.com ,企业邮箱:smtp.qiye.163.com
  9. # 腾讯的,个人smtp.qq.com, 企业的:smtp.exmail.qq.com
  10. host: smtp.qq.com
  11. username: xxx@qq.com
  12. # 口令是QQ邮箱开通的smtp服务后得到的客户端授权码,不是你的邮箱登录密码
  13. password: xxxxx
  14. default-encoding: UTF-8
  15. properties:
  16. mail:
  17. smtp:
  18. auth: true
  19. socketFactory:
  20. class: javax.net.ssl.SSLSocketFactory
  21. port: 465
  22. # 开启debug,方便查看邮件发送日志
  23. debug: true

项目目录结构图如下:

 

三、发送邮件

     首先定义接口MailService.java,如下所示。接口中定义了四个方法,分别是用来发送简单文本邮件、带附件邮件、带图片的邮件、使用Themeleaf构建邮件模板的。

  1. package com.ztt.service;
  2. import java.io.File;
  3. import java.util.List;
  4. public interface MailService {
  5. void sendSimpleMail(String mailFrom, String mailFromNick, String mailTo, String cc, String subject, String content);
  6. void sendMailWithAttachments(String mailFrom, String mailFromNick, String mailTo, String cc, String subject, String content,
  7. List<File> files);
  8. void sendMailWithImage(String mailFrom, String mailFromNick, String mailTo, String cc, String subject, String content,
  9. String[] imagePaths, String[] imageId);
  10. void sendHtmlMailThymeLeaf(String mailFrom, String mailFromNick, String mailTo, String cc, String subject, String content);
  11. }

       然后,是接口的实现类MailServiceImpl.java

       每个方法的功能,及关键代码都有注释。

  1. package com.ztt.service.impl;
  2. import com.ztt.service.MailService;
  3. import org.apache.commons.lang3.StringUtils;
  4. import org.slf4j.Logger;
  5. import org.slf4j.LoggerFactory;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.beans.factory.annotation.Value;
  8. import org.springframework.core.io.FileSystemResource;
  9. import org.springframework.mail.javamail.JavaMailSender;
  10. import org.springframework.mail.javamail.MimeMessageHelper;
  11. import org.springframework.stereotype.Service;
  12. import javax.mail.MessagingException;
  13. import javax.mail.internet.InternetAddress;
  14. import javax.mail.internet.MimeMessage;
  15. import java.io.File;
  16. import java.util.List;
  17. @Service("mailService")
  18. public class MailServiceImpl implements MailService {
  19. private static final Logger logger = LoggerFactory.getLogger(MailServiceImpl.class);
  20. /**
  21. * JavaMailSender是Spring Boot在MailSenderPropertiesConfiguration 类中配直好的,该类在 Mail
  22. * 自动配置类 MailSenderAutoConfiguration 中导入 因此这里注入 JavaMailSender 就可以使用了
  23. */
  24. @Autowired
  25. private JavaMailSender mailSender;
  26. /**
  27. * 1、发送普通文本邮件
  28. *
  29. * @param mailFrom 发件人邮箱
  30. * @param mailFromNick 发件人昵称
  31. * @param mailTo 收件人邮箱
  32. * @param cc 抄送人邮箱(可为空,方法内部处理)
  33. * @param subject 主题
  34. * @param content 内容
  35. */
  36. @Override
  37. public void sendSimpleMail(String mailFrom, String mailFromNick, String mailTo, String cc,
  38. String subject, String content) {
  39. try {
  40. // 多个收件人之间用英文逗号分隔
  41. String[] mailToArr = mailTo.split(",");
  42. for (String address : mailToArr) {
  43. // 简单邮件信息类
  44. MimeMessage mimeMessage = mailSender.createMimeMessage();
  45. // HTML邮件信息类
  46. MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage);
  47. // 昵称
  48. mimeMessageHelper.setFrom(new InternetAddress(mailFromNick + " <" + mailFrom + ">"));
  49. mimeMessageHelper.setTo(address);
  50. if (!StringUtils.isEmpty(cc)) {
  51. mimeMessageHelper.setCc(cc);
  52. }
  53. mimeMessageHelper.setSubject(subject);
  54. mimeMessageHelper.setText(content);
  55. mailSender.send(mimeMessage);
  56. }
  57. } catch (Exception e) {
  58. logger.error("发送邮件失败:", e);
  59. }
  60. }
  61. /**
  62. * 2、发送带附件的邮件
  63. *
  64. * @param mailFrom 发件人
  65. * @param mailFromNick 发件人昵称
  66. * @param mailTo 收件人
  67. * @param cc 抄送人
  68. * @param subject
  69. * @param content
  70. * @param files
  71. */
  72. @Override
  73. public void sendMailWithAttachments(String mailFrom, String mailFromNick, String mailTo, String cc,
  74. String subject, String content, List<File> files) {
  75. MimeMessage mimeMessage = mailSender.createMimeMessage();
  76. try {
  77. /*
  78. 第二个参数true表示构造一个multipart message类型的邮件,multipart message类型的邮件包含多个正文、附件以及内嵌资源,
  79. 邮件的表现形式更丰富
  80. */
  81. MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
  82. mimeMessageHelper.setFrom(new InternetAddress(mailFromNick + " <" + mailFrom + ">"));
  83. mimeMessageHelper.setSubject(subject);
  84. mimeMessageHelper.setText(content);
  85. // 设置多个收件人
  86. String[] toAddress = mailTo.split(",");
  87. mimeMessageHelper.setTo(toAddress);
  88. if (!StringUtils.isEmpty(cc)) {
  89. mimeMessageHelper.setCc(cc);
  90. }
  91. // 添加附件
  92. if (null != files) {
  93. for (File file : files) {
  94. // 通过addAttachment方法添加附件
  95. mimeMessageHelper.addAttachment(file.getName(), file);
  96. }
  97. }
  98. } catch (MessagingException e) {
  99. e.printStackTrace();
  100. }
  101. //发送邮件
  102. mailSender.send(mimeMessage);
  103. }
  104. /**
  105. * 3、正文内容带图片
  106. *
  107. * @param mailFrom
  108. * @param mailFromNick
  109. * @param mailTo
  110. * @param cc 抄送人
  111. * @param subject
  112. * @param content
  113. * @param imagePaths
  114. * @param imageId
  115. */
  116. @Override
  117. public void sendMailWithImage(String mailFrom, String mailFromNick, String mailTo, String cc, String subject,
  118. String content, String[] imagePaths, String[] imageId) {
  119. MimeMessage mimeMessage = mailSender.createMimeMessage();
  120. try {
  121. MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
  122. mimeMessageHelper.setFrom(new InternetAddress(mailFromNick + " <" + mailFrom + ">"));
  123. // 设置多个收件人
  124. String[] toAddress = mailTo.split(",");
  125. mimeMessageHelper.setTo(toAddress);
  126. if (!StringUtils.isEmpty(cc)) {
  127. mimeMessageHelper.setCc(cc);
  128. }
  129. mimeMessageHelper.setSubject(subject);
  130. // 第二个参数为true表示邮件正文是html格式的,默认是false
  131. mimeMessageHelper.setText(content, true);
  132. // 添加图片
  133. if (imagePaths != null && imagePaths.length != 0) {
  134. for (int i = 0; i < imagePaths.length; i++) {
  135. // 通过FileSystemResource构造静态资源
  136. FileSystemResource fileSystemResource = new FileSystemResource(imagePaths[i]);
  137. // 调用addInline方法将资源加入邮件对象中
  138. mimeMessageHelper.addInline(imageId[i], fileSystemResource);
  139. }
  140. }
  141. mailSender.send(mimeMessage);
  142. } catch (MessagingException e) {
  143. System.out.println(e);
  144. }
  145. }
  146. /**
  147. * 4、使用Themeleaf构建邮件模板。需额外加spring-boot-starter-thymeleaf依赖
  148. *
  149. * @param mailFrom
  150. * @param mailFromNick
  151. * @param mailTo
  152. * @param cc
  153. * @param subject
  154. * @param content
  155. */
  156. @Override
  157. public void sendHtmlMailThymeLeaf(String mailFrom, String mailFromNick, String mailTo, String cc,
  158. String subject, String content) {
  159. MimeMessage mimeMessage = mailSender.createMimeMessage();
  160. try {
  161. MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
  162. mimeMessageHelper.setFrom(new InternetAddress(mailFromNick + " <" + mailFrom + ">"));
  163. // 设置多个收件人
  164. String[] toAddress = mailTo.split(",");
  165. mimeMessageHelper.setTo(toAddress);
  166. if (!StringUtils.isEmpty(cc)) {
  167. mimeMessageHelper.setCc(cc);
  168. }
  169. mimeMessageHelper.setSubject(subject);
  170. // 第二个参数为true表示邮件正文是html格式的,默认是false
  171. mimeMessageHelper.setText(content, true);
  172. mailSender.send(mimeMessage);
  173. } catch (MessagingException e) {
  174. System.out.println(e);
  175. }
  176. }
  177. }

       然后是测试类SendmailApplicationTest.java:

       为了方便测试,我针对每个方法都单独写了个测试方法。只需要把相关邮箱换成自己的,相关文件图片换成自己的,就可以直接运行测试看结果的。每个方法都可单独直接运行,不要从Starter启动类启动。

  1. package com.ztt.controller;
  2. import com.ztt.service.MailService;
  3. import org.junit.Test;
  4. import org.junit.runner.RunWith;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.boot.test.context.SpringBootTest;
  7. import org.springframework.test.context.junit4.SpringRunner;
  8. import org.thymeleaf.TemplateEngine;
  9. import org.thymeleaf.context.Context;
  10. import java.io.File;
  11. import java.util.ArrayList;
  12. import java.util.List;
  13. @RunWith(SpringRunner.class)
  14. @SpringBootTest
  15. public class SendmailApplicationTest {
  16. @Autowired
  17. private MailService mailService;
  18. // 发件人要跟yml配置文件里填写的邮箱一致
  19. String mailFrom = "xx@qq.com";
  20. // 收件人
  21. String mailTo = "xx@newhope.cn";
  22. // 抄送
  23. String cc = "xx@163.com";
  24. /**
  25. * 1、测试普通邮件发送
  26. */
  27. @Test
  28. public void testSendSimpleMail() {
  29. String result = "发送邮件成功";
  30. try {
  31. mailService.sendSimpleMail(mailFrom, "一个大帅哥", mailTo, cc, "TestMail", "Hello World !");
  32. } catch (Exception e) {
  33. result = "发送邮件失败!";
  34. System.out.println(result);
  35. System.out.println(e);
  36. }
  37. System.out.println(result);
  38. }
  39. /**
  40. * 2、测试带附件的方法
  41. */
  42. @Test
  43. public void testSendAttachment() {
  44. File imgFile = new File("src\\main\\java\\com\\ztt\\controller\\f1bdd00e8c.jpg");
  45. File txtFile = new File("src\\main\\java\\com\\ztt\\controller\\hello.txt");
  46. List<File> fileList = new ArrayList<>();
  47. fileList.add(imgFile);
  48. fileList.add(txtFile);
  49. // 发件人要跟yml配置文件里填写的邮箱一致
  50. String mailFrom = "1798206908@qq.com";
  51. String mailTo = "zhaott@newhope.cn";
  52. String result = "发送邮件成功";
  53. try {
  54. mailService.sendMailWithAttachments(mailFrom, "一个大帅哥", mailTo, cc, "TestMail", "Hello World !", fileList);
  55. } catch (Exception e) {
  56. result = "发送邮件失败!";
  57. System.out.println(result);
  58. System.out.println(e);
  59. }
  60. System.out.println(result);
  61. }
  62. /**
  63. * 3、正文带图片
  64. */
  65. @Test
  66. public void testSendMailWithImage() {
  67. // 图片路径
  68. String image01Path = "E:\\personal\\gittest\\学习项目库\\learning_project_library\\SpringBoot_mail\\src\\main\\java\\com\\ztt\\controller\\2ed0c0d5a2.jpg";
  69. String image02Path = "E:\\personal\\gittest\\学习项目库\\learning_project_library\\SpringBoot_mail\\src\\main\\java\\com\\ztt\\controller\\3bcd0b6866.jpg";
  70. String[] imageArr = new String[]{image01Path, image02Path};
  71. String[] imageIdArr = new String[]{"image01", "image02"};
  72. String result = "发送邮件成功";
  73. try {
  74. String contentHtml = "这是图片1:<div><img src='cid:image01'/></div>" +
  75. "这是图片2:<div><img src='cid:image02'/></div>";
  76. mailService.sendMailWithImage(mailFrom, "一个大帅哥", mailTo, cc, "TestMail", contentHtml, imageArr, imageIdArr);
  77. } catch (Exception e) {
  78. result = "发送邮件失败!";
  79. System.out.println(result);
  80. System.out.println(e);
  81. }
  82. System.out.println(result);
  83. }
  84. /**
  85. * 4、使用ThymeLeaf
  86. */
  87. // 注入TemplateEngine
  88. @Autowired
  89. TemplateEngine templateEngine;
  90. @Test
  91. public void testSendHtmlMailThymeLeaf() {
  92. // 注意导入的包是org.thymeleaf.context
  93. Context context = new Context();
  94. context.setVariable("username", "比尔盖茨");
  95. context.setVariable("age", "18");
  96. String content = templateEngine.process("mailTemplate01.html", context);
  97. mailService.sendHtmlMailThymeLeaf(mailFrom, "一个大帅哥", mailTo, cc, "TestMail", content);
  98. System.out.println("邮件发送成功");
  99. }
  100. }

发送普通文本邮件和带附件的邮件比较简单。这里就不作介绍了。

首先说一下第三种。。

  1. sendMailWithImage(String mailFrom, String mailFromNick, String mailTo, String cc, String subject,
  2. String content, String[] imagePaths, String[] imageId)
这个方法实现了正文带图片的功能。不同于前两种的是,String content是html格式的文本,里面用cid标注静态资源(本文是src='cid:image01'),String[] imagePaths存储的是图片的路径,String[] imageId存储了每张图片的编号,这个编号是可以自己随便定义的,但是必须跟content里面使用的cid名称一致。

       然后说一下第四种。

       对于格式复杂的邮件,如果采用字符串进行html拼接,不但容易出错,而且不易于维护,使用html模板可以很好的解决这一问题。模板可以选择FreeMaker或者ThymeLeaf,使用Thymeleaf构建邮件模板,更加方便。本文使用的也是Thymeleaf。使用Thymeleaf,首先需要添加Thymeleaf的依赖,参考开头的pom文件。

       Thymeleaf邮件模板默认位置是在resources/templates目录下,创建相应的目录,然后创建邮件模板,mailTemplate01.html。如下所示:

  1. <!DOCTYPE html>
  2. <html lang="en" xmlns:th="http://www.thymeleaf.org">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <h2>
  9. 通过ThymeLeaf发送html邮件
  10. </h2>
  11. <table border="1">
  12. <tr>
  13. <td>用户名</td>
  14. <!--使用th,html标签内要导入xmlns:th="http://www.thymeleaf.org"-->
  15. <td th:text="${username}"></td>
  16. </tr>
  17. <tr>
  18. <td>年龄</td>
  19. <td th:text="${age}"></td>
  20. </tr>
  21. </table>
  22. <div>
  23. 这是一张图片:
  24. </div>
  25. <div>
  26. <img src="E:\personal\gittest\学习项目库\learning_project_library\SpringBoot_mail\src\main\java\com\ztt\controller\2ed0c0d5a2.jpg"/>
  27. </div>
  28. </body>
  29. </html>

       这个模板是我随便写的,只定义了一个表格,然后放了张图片进去。

       Thymeleaf 提供了 TemplateEngine 来对模板进行渲染,通过 Context 构造 模板中变量需要的值,然后在html文件中通过th:text="${username}"的方式来引用。
 

       效果如下:

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/553196
推荐阅读
相关标签
  

闽ICP备14008679号