天天看點

springboot中實作發送郵件功能

發送郵件的功能有時在業務中還是需要使用到的,比如訂單方面的業務,使用者下單後需要給使用者發送一個訂單相關的郵件;又或者是某些系統在業務層來內建預警功能,出現問題時及時給開發和運維發送預警郵件。那麼,接下來将講一下在springboot項目中郵件發送功能的內建與其簡單的使用。

依賴引入

首先,在POM檔案中加入如下依賴:

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

springboot為我們提供了這個郵件相關的stater,旨在更友善引入依賴和進行配置。

spring-boot-starter-mail

主要包含了如下與郵件相關的依賴包:

  • org.springframework:spring-context-support
    • org.springframework.mail
  • com.sun.mail.javax.email

其中,spring的mail是在javax的mail上做了更抽象的封裝,友善我們使用。仔細檢視源碼,就會觀察到如下一些關鍵的類:

  • 郵件發送:MailSender -> JavaMailSender -> JavaMailSenderImpl
  • 郵件消息包裝:MailMessasge, SimpleMailMessage, MimeMailMessage
  • 郵件消息的helper:MimeMessageHelper

配置設定

在application.yml中加入郵件相關的配置,項目啟動後便會在spring的bean容器中注入MailSender和JavaMailSender(他們有共同的實作類JavaMailSenderImpl),之後便可以在代碼中使用相關的方法實作發送郵件的功能了。配置資訊如下:

spring:
  mail:
    host: smtp.163.com
    port: 25
    username: [email protected]
    password: 用戶端授權碼
           

使用案例

依賴已引入,亦完成mail相關的配置設定,接下來就該來實作發送郵件的功能了。郵件的的發送涉及如下相關:

  • 簡單郵件内容發送
  • MIME(Multipurpose Internet Mail Extensions)多用途網際網路郵件擴充類型的郵件類型

首先,來定義一個簡單的實體(使用了Lombok,詳見Lombok插件講解),表示郵件相關的資訊,如下:

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Message {

    /**
     * 收件人
     */
    private String to;
    /**
     * 發件人
     */
    private String from;
    /**
     * 郵件主題
     */
    private String subject;
    /**
     * 郵件内容
     */
    private String text;
    /**
     * 附件
     */
    private String attachment;
    /**
     * 嵌入資源
     */
    private String inlineResource;
}
           

這裡隻定義了正常内容,抄送CC(Carbon Copy),加密抄送BCC(Blind Carbon Copy)就不再說明了。

郵件内容的包裝可以是

SimpleMailMessage

,又或者是

MimeMailMessage

,顧名思義便能想到這兩個類的用途,接下來便來說明簡單郵件内容的發送、發送附件和内容内嵌資源(圖檔,音頻)等功能。

簡單内容發送

使用

SimpleMailMessage

來包裝郵件資訊,使用

MailSender

來執行發送事件,代碼如下:

public void sendSimpleMessage(Message message) {
        SimpleMailMessage msg = new SimpleMailMessage();
        msg.setFrom(message.getFrom());
        msg.setTo(message.getTo());
        msg.setSubject(message.getSubject());
        msg.setText(message.getText());
        mailSender.send(msg);
    }
           

使用

MimeMessagePreparator

來包裝

MimeMailMessage

郵件資訊,使用

JavaMailSender

來執行發送事件,代碼如下:

public void sendPreparatorMimeMessage(Message message) {
        MimeMessagePreparator preparator = mimeMessage -> {
            mimeMessage.setFrom(message.getFrom());
            mimeMessage.setRecipients(javax.mail.Message.RecipientType.TO, message.getTo());
            mimeMessage.setSubject(message.getSubject());
            mimeMessage.setText(message.getText());
        };
        javaMailSender.send(preparator);
    }
           

使用

MimeMessageHelper

來包裝

MimeMailMessage

郵件資訊,使用

JavaMailSender

來執行發送事件,代碼如下:

public void sendBasicMimeMessage(Message message) {
        MimeMailMessage mimeMailMessage = new MimeMailMessage(javaMailSender.createMimeMessage());
        try {
            MimeMessageHelper helper = mimeMailMessage.getMimeMessageHelper();
            helper.setTo(message.getTo());
            helper.setFrom(message.getFrom());
            helper.setSubject(message.getSubject());
            helper.setText(message.getText());
        } catch (MessagingException e) {
            log.error("build mail message error");
        }
        javaMailSender.send(mimeMailMessage.getMimeMessage());

    }
           

發送附件内容

附件功能隻能使用

MimeMailMessage

進行郵件資訊包裝,可以添加單個郵件,多個郵件,這裡以單個郵件為例,代碼如下:

public void sendAttachmentsMimeMessage(Message message) {
        MimeMailMessage mimeMailMessage = new MimeMailMessage(javaMailSender.createMimeMessage());
        try {
            MimeMessageHelper helper = new MimeMessageHelper(mimeMailMessage.getMimeMessage(), true);
            helper.setFrom(message.getFrom());
            helper.setTo(message.getTo());
            helper.setSubject(message.getSubject());
            helper.setText(message.getText());
            FileSystemResource file = new FileSystemResource(new File(message.getAttachment()));
            helper.addAttachment(file.getFilename(), file);
        } catch (MessagingException e) {
            log.error("build mail message error");
        }
        javaMailSender.send(mimeMailMessage.getMimeMessage());
    }
           

嵌入資源内容

嵌入資源功能亦隻能使用

MimeMailMessage

進行郵件資訊包裝,這裡以在郵件内容中嵌入一張圖檔為例,“resource1234”是資源的id,確定在郵件嵌入資源中唯一,才能正确引入到html。代碼如下:

public void sendInlineImageMimeMessage(Message message) {
        MimeMailMessage mimeMailMessage = new MimeMailMessage(javaMailSender.createMimeMessage());
        try {
            MimeMessageHelper helper = new MimeMessageHelper(mimeMailMessage.getMimeMessage(), true);
            helper.setFrom(message.getFrom());
            helper.setTo(message.getTo());
            helper.setSubject(message.getSubject());
            String html = "<html><body><img src='cid:resource1234'></body></html>";
            helper.setText(message.getText(), html);
            FileSystemResource resource = new FileSystemResource(new File(message.getInlineResource()));
            helper.addInline("resource1234", resource);
        } catch (MessagingException e) {
            log.error("build mail message error");
        }
        javaMailSender.send(mimeMailMessage.getMimeMessage());
    }
           

測試驗證

下面貼出單元測試代碼:

package com.lazycece.sbac.mail.manager;

import com.lazycece.sbac.mail.entity.Message;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;

/**
 * @author lazycece
 * @date 2019/5/21
 */
@SpringBootTest
@RunWith(SpringRunner.class)
public class MailManagerTest {

    @Resource
    private MailManager mailManager;

    private Message.MessageBuilder commonMail() {
        return Message.builder()
                .from("[email protected]")
                .to("[email protected]")
                .subject("你好");
    }

    @Test
    public void testSendSimpleMessage() {
        Message message = commonMail()
                .text("Hello, simple message ! ")
                .build();
        mailManager.sendSimpleMessage(message);
    }

    @Test
    public void testSendPreparatorMimeMessage() {
        Message message = commonMail()
                .text("Hello, preparator mime message ! ")
                .build();
        mailManager.sendPreparatorMimeMessage(message);
    }

    @Test
    public void sendBasicMimeMessage() {
        Message message = commonMail()
                .text("Hello, basic mime email ! ")
                .build();
        mailManager.sendBasicMimeMessage(message);
    }

    @Test
    public void sendAttachmentsMimeMessage() {
        Message message = commonMail()
                .text("Hello, attachment mime email ! ")
                .attachment("/home/lazycece/下載下傳/temp.png")
                .build();
        mailManager.sendAttachmentsMimeMessage(message);
    }

    @Test
    public void sendInlineImageMimeMessage() {
        Message message = commonMail()
                .text("Hello, inline image mime email ! ")
                .inlineResource("/home/lazycece/下載下傳/temp.png")
                .build();
        mailManager.sendInlineImageMimeMessage(message);
    }
}
           

案例源碼

案例源碼位址:https://github.com/lazycece/springboot-actual-combat/tree/master/springboot-ac-email

繼續閱讀