1. 程式人生 > >SpringBoot 傳送郵件功能實現

SpringBoot 傳送郵件功能實現

背景

有個小夥伴問我你以前發郵件功能怎麼弄的。然後我就給他找了個demo,正好在此也寫一下,分享給大家。

理清痛點

傳送郵件,大家可以想一下,坑的地方在哪?
我覺得是三個吧。
第一:郵件白名單問題。
第二:郵件超時問題。
第三:郵件帶附件問題。
我下面的demo都會介紹這些問題及解決。

實現方案

準備工作

我們先要準備一個可以傳送的郵箱,我這裡以我的163郵箱為例,現在傳送郵件的規則,要求你輸入一種叫做授權碼的東西,注意這個東西不是密碼。
獲取授權碼的步驟:



當選擇開啟,通過驗證之後就可以獲取到驗證碼。選擇重置驗證碼也可以獲取。以前17年的時候就寫過一個demo,現在19年又開了一個,因為以前的忘了。

SpringBoot專案引入郵件包

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

yml配置郵件相關

spring:
  mail:
    # 郵件服務地址
    host: smtp.163.com
    # 埠,可不寫預設
    port: 25
    # 編碼格式
    default-encoding: utf-8
    # 使用者名稱
    username: [email protected]
    # 授權碼,就是我們剛才準備工作獲取的程式碼
    password: xxx
    # 其它引數
    properties:
      mail:
        smtp:
          # 如果是用 SSL 方式,需要配置如下屬性,使用qq郵箱的話需要開啟
          ssl:
            enable: true
            required: true
          # 郵件接收時間的限制,單位毫秒
          timeout: 10000
          # 連線時間的限制,單位毫秒
          connectiontimeout: 10000
          # 郵件傳送時間的限制,單位毫秒
          writetimeout: 10000

針對於上面提的超時問題,捕獲超時異常就可解決。

郵件傳送工具類

主要通過以下工具類就可以滿足傳送java郵件的需要。當我們進行好 yml 配置後,SpringBoot會幫助我們自動配置 JavaMailSender 我們通過這個java類就可以實現操作java來發送郵件。以下列舉了幾種常用的郵件。

@Service
public class MailService {
    private static final Logger logger = LoggerFactory.getLogger(MailServiceImpl.class);

    @Autowired
    private JavaMailSender mailSender;

    private static final String SENDER = "[email protected]";

    /**
     * 傳送普通郵件
     *
     * @param to      收件人
     * @param subject 主題
     * @param content 內容
     */
    @Override
    public void sendSimpleMailMessge(String to, String subject, String content) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(SENDER);
        message.setTo(to);
        message.setSubject(subject);
        message.setText(content);
        try {
            mailSender.send(message);
        } catch (Exception e) {
            logger.error("傳送簡單郵件時發生異常!", e);
        }
    }

    /**
     * 傳送 HTML 郵件
     *
     * @param to      收件人
     * @param subject 主題
     * @param content 內容
     */
    @Override
    public void sendMimeMessge(String to, String subject, String content) {
        MimeMessage message = mailSender.createMimeMessage();
        try {
            //true表示需要建立一個multipart message
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(SENDER);
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(content, true);
            mailSender.send(message);
        } catch (MessagingException e) {
            logger.error("傳送MimeMessge時發生異常!", e);
        }
    }

    /**
     * 傳送帶附件的郵件
     *
     * @param to       收件人
     * @param subject  主題
     * @param content  內容
     * @param filePath 附件路徑
     */
    @Override
    public void sendMimeMessge(String to, String subject, String content, String filePath) {
        MimeMessage message = mailSender.createMimeMessage();
        try {
            //true表示需要建立一個multipart message
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(SENDER);
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(content, true);

            FileSystemResource file = new FileSystemResource(new File(filePath));
            String fileName = file.getFilename();
            helper.addAttachment(fileName, file);

            mailSender.send(message);
        } catch (MessagingException e) {
            logger.error("傳送帶附件的MimeMessge時發生異常!", e);
        }
    }

    /**
     * 傳送帶靜態檔案的郵件
     *
     * @param to       收件人
     * @param subject  主題
     * @param content  內容
     * @param rscIdMap 需要替換的靜態檔案
     */
    @Override
    public void sendMimeMessge(String to, String subject, String content, Map<String, String> rscIdMap) {
        MimeMessage message = mailSender.createMimeMessage();
        try {
            //true表示需要建立一個multipart message
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(SENDER);
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(content, true);

            for (Map.Entry<String, String> entry : rscIdMap.entrySet()) {
                FileSystemResource file = new FileSystemResource(new File(entry.getValue()));
                helper.addInline(entry.getKey(), file);
            }
            mailSender.send(message);
        } catch (MessagingException e) {
            logger.error("傳送帶靜態檔案的MimeMessge時發生異常!", e);
        }
    }
}

傳送郵件的demo

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbooEmailDemoApplicationTests {

    @Autowired
    private MailService mailService;

    private static final String TO = "[email protected]";
    private static final String SUBJECT = "測試郵件";
    private static final String CONTENT = "test content";

    /**
     * 測試傳送普通郵件
     */
    @Test
    public void sendSimpleMailMessage() {
        mailService.sendSimpleMailMessge(TO, SUBJECT, CONTENT);
    }

    /**
     * 測試傳送html郵件
     */
    @Test
    public void sendHtmlMessage() {
        String htmlStr = "<h1>Test</h1>";
        mailService.sendMimeMessge(TO, SUBJECT, htmlStr);
    }

    /**
     * 測試傳送帶附件的郵件
     * @throws FileNotFoundException
     */
    @Test
    public void sendAttachmentMessage() throws FileNotFoundException {
        File file = ResourceUtils.getFile("classpath:test.txt");
        String filePath = file.getAbsolutePath();
        mailService.sendMimeMessge(TO, SUBJECT, CONTENT, filePath);
    }

    /**
     * 測試傳送帶附件的郵件
     * @throws FileNotFoundException
     */
    @Test
    public void sendPicMessage() throws FileNotFoundException {
        String htmlStr = "<html><body>測試:圖片1 <br> <img src=\'cid:pic1\'/> <br>圖片2 <br> <img src=\'cid:pic2\'/></body></html>";
        Map<String, String> rscIdMap = new HashMap<>(2);
        rscIdMap.put("pic1", ResourceUtils.getFile("classpath:pic01.jpg").getAbsolutePath());
        rscIdMap.put("pic2", ResourceUtils.getFile("classpath:pic02.jpg").getAbsolutePath());
        mailService.sendMimeMessge(TO, SUBJECT, htmlStr, rscIdMap);
    }
}

白名單問題

如果是傳送給固定郵箱,可以直接在固定郵箱裡面設定白名單,如果頻繁的傳送給多個郵箱,最好設定以下發送時間間隔,不要不斷的給某一個郵箱傳送。

總結

至此SpringBoot傳送郵件介紹完畢,大家可以直接使用程式碼來進行傳送