邮件发送

本篇主要介绍了Spring Boot中邮件发送,分别讲解了简单的文本邮件、HTML邮件、附件邮件、图片邮件、模板邮件。

快速导航

添加maven依赖

Spring Boot项目的pom.xml文件中引入spring-boot-starter-email依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-email</artifactId>
  4. <scope>email</scope>
  5. </dependency>

模版邮件需要引入 spring-boot-starter-thymeleaf 插件

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-thymeleaf</artifactId>
  4. </dependency>

配置文件增加邮箱相关配置

163邮箱配置,注意要替换自己的账户信息,password为授权码。

  1. ```yml
  2. spring:
  3. mail:
  4. host: smtp.163.com
  5. username: your163account@163.com
  6. password: your163password
  7. default-encoding: utf-8

QQ邮箱发送邮件配置,以下password为授权码

  1. spring:
  2. mail:
  3. host: smtp.qq.com
  4. username: yourqqaccount@qq.com
  5. password: yourQQpassword

项目构建

基于上节单元测试chapter5-1代码示例基础之上编写

业务层代码

service目录下创建MailService.java文件,负责业务层邮件发送功能编写

让我们利用Spring提供的JavaMailSender接口实现邮件发送,在项目中使用到地方用@Autowired注入邮件发送对象

  1. ```java
  2. package com.angelo.service;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.beans.factory.annotation.Value;
  5. import org.springframework.core.io.FileSystemResource;
  6. import org.springframework.mail.SimpleMailMessage;
  7. import org.springframework.mail.javamail.JavaMailSender;
  8. import org.springframework.mail.javamail.MimeMessageHelper;
  9. import org.springframework.stereotype.Service;
  10. import javax.mail.MessagingException;
  11. import javax.mail.internet.MimeMessage;
  12. import java.io.File;
  13. @Service
  14. public class MailService {
  15. @Value("${spring.mail.username}")
  16. private String from;
  17. @Autowired // 项目启动时将mailSender注入
  18. private JavaMailSender javaMailSender;
  19. // ... 下面会一一介绍 ...
  20. }

单元测试层代码

test测试目录下创建MailServiceTest.java测试类,对业务层代码进行单元测试

  1. ```java
  2. package com.angelo.service;
  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 javax.annotation.Resource;
  11. import javax.mail.MessagingException;
  12. import java.lang.reflect.Array;
  13. import static org.junit.Assert.*;
  14. @RunWith(SpringRunner.class)
  15. @SpringBootTest
  16. public class MailServiceTest {
  17. @Autowired
  18. private MailService mailService;
  19. @Resource
  20. TemplateEngine templateEngine;
  21. String to = "your163password@163.com";
  22. // ... 下面为一一介绍 ...
  23. }

五种邮件发送类型讲解

文本邮件

  1. * 业务层```MailService.java
  1. /**
  2. * 发送文本邮件
  3. * @param to
  4. * @param subject
  5. * @param content
  6. */
  7. public void sendTextMail(String to, String subject, String content) {
  8. SimpleMailMessage message = new SimpleMailMessage();
  9. message.setTo(to); // 发送对象
  10. message.setSubject(subject); // 邮件主题
  11. message.setText(content); // 邮件内容
  12. message.setFrom(from); // 邮件的发起者
  13. javaMailSender.send(message);
  14. }

对以上业务代码进行单元测试,查看下效果

  • 单元测试层MailServiceTest.java

    1. @Test
    2. public void sendTextEmailTest() {
    3. mailService.sendTextMail(to, "发送文本邮件", "hello,这是Spring Boot发送的一封文本邮件!");
    4. }
  • 测试结果

邮件发送 - 图1

html邮件

基于MimeMessageHelper创建helper对象,设置setText第二个参数为true,将会使用html格式打印邮件。

  • 业务层MailService.java

    1. /**
    2. * 发送HTMl邮件
    3. * @param to
    4. * @param subject
    5. * @param content
    6. * @throws MessagingException
    7. */
    8. public void sendHtmlMail(String to, String subject, String content) throws MessagingException {
    9. MimeMessage message = javaMailSender.createMimeMessage();
    10. MimeMessageHelper helper = new MimeMessageHelper(message, true);
    11. helper.setFrom(from);
    12. helper.setTo(to);
    13. helper.setSubject(subject);
    14. helper.setText(content, true);
    15. javaMailSender.send(message);
    16. }
  • 单元测试层MailServiceTest.java

    1. @Test
    2. public void sendHtmlEmailTest() throws MessagingException {
    3. String content = "<html>" +
    4. "<body>" +
    5. "<h1 style=\"" + "color:red;" + "\">hello,这是Spring Boot发送的一封HTML邮件</h1>" +
    6. "</body></html>";
    7. mailService.sendHtmlMail(to, "发送HTML邮件", content);
    8. }
  • 测试结果

可以看到邮件结果使用了例子中预先设置好的邮件格式

邮件发送 - 图2

附件邮件

  • 业务层MailService.java

    1. /**
    2. * 发送带附件的邮件
    3. * @param to
    4. * @param subject
    5. * @param content
    6. * @param filePathList
    7. * @throws MessagingException
    8. */
    9. public void sendAttachmentMail(String to, String subject, String content, String[] filePathList) throws MessagingException {
    10. MimeMessage message = javaMailSender.createMimeMessage();
    11. MimeMessageHelper helper = new MimeMessageHelper(message, true);
    12. helper.setFrom(from);
    13. helper.setTo(to);
    14. helper.setSubject(subject);
    15. helper.setText(content, true);
    16. for (String filePath: filePathList) {
    17. System.out.println(filePath);
    18. FileSystemResource fileSystemResource = new FileSystemResource(new File(filePath));
    19. String fileName = fileSystemResource.getFilename();
    20. helper.addAttachment(fileName, fileSystemResource);
    21. }
    22. javaMailSender.send(message);
    23. }
  1. * 单元测试层```MailServiceTest.java
  1. @Test
  2. public void sendAttachmentEmailTest() throws MessagingException {
  3. String[] filePathList = new String[2];
  4. filePathList[0] = "/SpringBoot-WebApi/chapter4.zip";
  5. filePathList[1] = "/SpringBoot-WebApi/chapter5.zip";
  6. mailService.sendAttachmentMail(to, "发送附件邮件", "hello,这是Spring Boot发送的一封附件邮件!", filePathList);
  7. }
  • 测试结果

邮件发送 - 图3

html内嵌图片邮件

也是基于html邮件发送,通过内嵌图片等静态资源,可以直接看到图片。

  • 业务层MailService.java

    1. /**
    2. * 发送html内嵌图片的邮件
    3. * @param to
    4. * @param subject
    5. * @param content
    6. * @param srcPath
    7. * @param srcId
    8. * @throws MessagingException
    9. */
    10. public void sendHtmlInlinePhotoMail(String to, String subject, String content, String srcPath, String srcId) throws MessagingException {
    11. MimeMessage message = javaMailSender.createMimeMessage();
    12. MimeMessageHelper helper = new MimeMessageHelper(message, true);
    13. helper.setFrom(from);
    14. helper.setTo(to);
    15. helper.setSubject(subject);
    16. helper.setText(content, true);
    17. FileSystemResource fileSystemResource = new FileSystemResource(new File(srcPath));
    18. helper.addInline(srcId, fileSystemResource);
    19. javaMailSender.send(message);
    20. }

以下单元测试中srcPath为您的本地图片路径,srcId要和上面业务层的helper.addInline(srcId, fileSystemResource)srcId保持一致。

  • 单元测试层MailServiceTest.java

    1. @Test
    2. public void sendHtmlInlinePhotoMailTest() throws MessagingException {
    3. String srcPath = "/SpringBoot-WebApi/chapter6/img/pic18.jpg";
    4. String srcId = "pic18";
    5. String content = "<html>" +
    6. "<body>" +
    7. "<h2>hello,这是Spring Boot发送的一封HTML内嵌图片的邮件</h2>" +
    8. "<img src=\'cid:"+ srcId +"\'></img>" +
    9. "</body></html>";
    10. mailService.sendHtmlInlinePhotoMail(to, "发送图片邮件", content, srcPath, srcId);
    11. }
  • 测试结果

邮件发送 - 图4

模板邮件

邮件内容相对简单的情况下,我们可以选择使用以上几种简单邮件发送方法,在复杂业务中需要用到html结构,且html里的数据还需要动态修改,还是选择模版邮件,可以使用Freemarkerthymeleaf等模板引擎,这里主要介绍使用thymeleaf

  • 邮件模板编写
  1. ```html
  2. <!DOCTYPE html>
  3. <html lang="en" xmlns:th="http://www.thymeleaf.org">
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>模板邮件</title>
  7. </head>
  8. <body>
  9. 您好,<span th:text="${username}"></span>,欢迎访问我的个人博客:
  10. <a href="https://github.com/Q-Angelo/summarize">Github</a>、
  11. <a th:href="@{https://www.imooc.com/u/{id}(id=${id})}" href="#">慕课网</a>
  12. </body>
  13. </html>

利用上面介绍的发送html邮件即可,在单元测试文件中增加一个方法进行测试。

  • 单元测试层MailServiceTest.java

    1. @Test
    2. public void testTemplateEmailTest() throws MessagingException {
    3. Context context = new Context();
    4. context.setVariable("username", "张三");
    5. context.setVariable("id", "2667395");
    6. String emailContent = templateEngine.process("emailTemplate", context);
    7. mailService.sendHtmlMail(to, "发送模板邮件", emailContent);
    8. }
  • 测试结果

邮件发送 - 图5

常见问题

出现这个错误的原因是网易将我发送的邮件当成了垃圾邮件,<<发送163文本邮件>>这是我填写的邮件标题,后来发现网易是对标题里面含了163导致的,大家遇到类似问题多检查下。

  1. com.sun.mail.smtp.SMTPSendFailedException: 554 DT:SPM 163 smtp10,DsCowADH1MxWegtcyxFjDw--.48939S2 1544256086

如遇到其他什么可在issues中提问

Github查看本文完整示例 chapter6-1