­

Spring Boot (十二): Spring Boot 郵件服務

  • 2019 年 10 月 14 日
  • 筆記

最早我們發郵件的時候是使用 JavaMail 來發送郵件,而在 Spring Boot 中, Spring Boot 幫我們將 JavaMail 封裝好了,是可以直接拿來使用的。

1. 依賴文件 pom.xml

代碼清單:spring-boot-mail/pom.xml
***

<dependencies>      <dependency>          <groupId>org.springframework.boot</groupId>          <artifactId>spring-boot-starter-mail</artifactId>      </dependency>      <dependency>          <groupId>org.springframework.boot</groupId>          <artifactId>spring-boot-starter-thymeleaf</artifactId>      </dependency>        <dependency>          <groupId>org.springframework.boot</groupId>          <artifactId>spring-boot-starter-test</artifactId>          <scope>test</scope>      </dependency>  </dependencies>
  • spring-boot-starter-thymeleaf 引入這個模版引擎是因為我們在發送郵件的時候,各種格式使用 HTML 的方式更容易實現,同樣我們也可以使用 freeMark , Spring Boot 同樣為我們提供了依賴包。

2. 配置文件 application.yml

代碼清單:
***

server:    port: 8080  spring:    application:      name: spring-boot-mail    mail:      host: smtp.qq.com      username: 136736247      password: xxxxxx      default-encoding: UTF-8      fromAddr: 136736247@qq.com      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
***

@Service  public class MailServiceImpl implements MailService {        private final Logger logger = LoggerFactory.getLogger(this.getClass());        @Autowired      private JavaMailSender javaMailSender;        @Value("${spring.mail.fromAddr}")      private String from;        @Value("${spring.mail.nickName}")      private String nickName;        @Override      public void sendSimpleEmail(String to, String subject, String content) {          SimpleMailMessage simpleMailMessage = new SimpleMailMessage();          simpleMailMessage.setFrom(nickName + "<" + from + ">");          simpleMailMessage.setTo(to);          simpleMailMessage.setSubject(subject);          simpleMailMessage.setText(content);            try{              javaMailSender.send(simpleMailMessage);              logger.info("簡易郵件發送成功");          } catch(Exception e) {              logger.error("簡易郵件發送異常", e);          }        }  }

3.2 測試類

代碼清單:spring-boot-mail/src/test/java/com/springboot/springbootmail/SpringBootMailApplicationTests.java
***

@Autowired  MailService mailService;    @Test  public void sendSimpleEmail() {      mailService.sendSimpleEmail("inwsy@hotmail.com", "測試郵件題目", "測試郵件內容");  }

這裡郵件發送至本人的 Hotmail 郵箱。

4. 發送 HTML 格式的郵件

4.1 實現類

代碼清單:spring-boot-mail/src/main/java/com/springboot/springbootmail/service/impl/MailServiceImpl.java
***

@Override  public void sendHTMLEmail(String to, String subject, String content) {      MimeMessage message = javaMailSender.createMimeMessage();        try {          MimeMessageHelper messageHelper = new MimeMessageHelper(message, true);            messageHelper.setFrom(new InternetAddress(from, nickName, "UTF-8"));          messageHelper.setTo(to);          messageHelper.setSubject(subject);          messageHelper.setText(content, true);            javaMailSender.send(message);            logger.info("HTML 模版郵件發送成功");      } catch (MessagingException e) {          logger.error("HTML 模版郵件發送失敗", e);      } catch (UnsupportedEncodingException e) {          logger.error("收件地址編碼異常", e);      }    }

4.2 頁面模版

代碼清單:spring-boot-mail/src/main/resources/templates/email.html
***

<!DOCTYPE html>  <html lang="zh" xmlns:th="http://www.thymeleaf.org">      <head>          <meta charset="UTF-8"/>          <title>郵件模版</title>      </head>      <body>          這是郵件模版生成的郵件,可以點擊鏈接查看詳情。          <a href="#" th:href="@{ http://www.geekdigging.com/ }">查看詳情。</a>          當前的Code為:<span th:text="${code}"></span>      </body>  </html>

這裡添加了動態內容 code ,在日常的開發中,我們使用發送驗證碼,動態生成內容是很有必要的。

4.3 測試類

代碼清單:spring-boot-mail/src/test/java/com/springboot/springbootmail/SpringBootMailApplicationTests.java
***

@Test  public void sendHTMLTemplateMail() {      Context context = new Context();      context.setVariable("code", "123456");      String emailHTMLContent = templateEngine.process("email", context);        mailService.sendHTMLEmail("inwsy@hotmail.com", "測試 HTML 模版郵件", emailHTMLContent);  }

5. 發送帶附件的郵件

5.1 實現類

代碼清單:spring-boot-mail/src/main/java/com/springboot/springbootmail/service/impl/MailServiceImpl.java
***

@Override  public void sendAttachmentsMail(String to, String subject, String content, String fileName, String filePath) {        MimeMessage message = javaMailSender.createMimeMessage();        try {          MimeMessageHelper messageHelper = new MimeMessageHelper(message, true);            messageHelper.setFrom(new InternetAddress(from, nickName, "UTF-8"));          messageHelper.setTo(to);          messageHelper.setSubject(subject);          messageHelper.setText(content, true);            FileSystemResource file = new FileSystemResource(new File(filePath));          messageHelper.addAttachment(fileName, file);            javaMailSender.send(message);            logger.info("帶附件郵件發送成功");      } catch (MessagingException e) {          logger.error("帶附件郵件發送失敗", e);      } catch (UnsupportedEncodingException e) {          logger.error("收件地址編碼異常", e);      }  }

注意: 如果需要發送多個附件,寫多個 messageHelper.addAttachment(fileName, file); 即可。

5.2 測試類

代碼清單:spring-boot-mail/src/test/java/com/springboot/springbootmail/SpringBootMailApplicationTests.java
***

@Test  public void sendAttachmentsMail() {        String fileName = "圖片.jpg";      String filePath = "C:\Users\inwsy\Downloads\0370279582fe3e2a8012060c896a5dd.jpg";        mailService.sendAttachmentsMail("inwsy@hotmail.com", "測試帶附件的郵件", "詳細請查閱附件", fileName, filePath);  }

6. 小結

在實際的開發過程中,郵件發送失敗是一件比較經常出現的事情,比如:網絡堵塞、對方拒收等情況,一般在郵件系統的設計中,可以先將要發送的數據寫入數據中,等發送完成後再修改標記位,再增加一個保障機制,例如增加一個定時任務,將一段時間內,發送失敗並重試次數小於一定閥值的內容再次進行發送,如果郵件系統的壓力過大,可以選擇使用異步的方式來進行發送,比如使用消息隊列進行承壓。

7. 示例代碼

示例代碼-Github

示例代碼-Gitee

7. 參考

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