1. 程式人生 > >Spring Boot 使用 QQ郵箱發郵件

Spring Boot 使用 QQ郵箱發郵件

maven依賴包如下

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

<!-- javax.mail -->
<dependency>
    <groupId>com.sun.mail</groupId>
    <artifactId>javax.mail</artifactId>
    <version>1.6.0</version>
</dependency>

一、登入QQ郵箱,點選【設定】後再點選【賬戶】,再往下翻,找到【POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服務】這一欄
在這裡插入圖片描述
開啟如圖所示中的三項(非強制,這三項是根據需要開通的),我這裡要求開啟第一個
在這裡插入圖片描述
注意圖中圈出的【生成授權碼】,點選後可以生成一個授權碼,然後記錄它,待會專案中配置需要
在這裡插入圖片描述

二、在配置檔案【application.yml】寫好配置,我的配置檔案區分了環境(大家可以無視),預設的應該是application.yml
在這裡插入圖片描述
引數說明:【host】、【port】、【debug】預設配置就好了,debug的話生產建議關掉,【username】是你的QQ郵箱號,【password】是你剛才申請的授權碼

三、在程式碼中建立一個Configuration,用來載入剛才在 application.yml 中配置的資料。這裡特別提一下,我採用@Bean的方式注入 JavaMailSenderImpl,在後面用的時候直接以 @Autowired 注入該類

package cn.xt.app.base.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSenderImpl;

import java.util.Properties;

/**
 * create: xiaotian
 * date: 2018/10/20
 */
@Configuration
public class MailConfig {

    @Value("${mail.host}")
    private String mailHost;

    @Value("${mail.port}")
    private Integer mailPort;

    @Value("${mail.debug}")
    private String mailDebug;

    @Value("${mail.username}")
    private String mailUsername;

    @Value("${mail.password}")
    private String mailPassword;

    @Bean(name = "javaMailSender")
    public JavaMailSenderImpl javaMailSender(){
        // 預設配置相關
        JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
        javaMailSender.setHost(mailHost);
        javaMailSender.setPort(mailPort);
        javaMailSender.setUsername(mailUsername);
        javaMailSender.setPassword(mailPassword);

        // 認證相關
        Properties properties = new Properties();
        properties.setProperty("mail.host", mailHost);
        properties.setProperty("mail.transport.protocol", "smtp");
        properties.setProperty("mail.smtp.auth", "true");
        properties.setProperty("mail.smtp.port", String.valueOf(mailPort));
        properties.setProperty("mail.smtp.socketFactory.port", String.valueOf(mailPort));
        properties.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        javaMailSender.setJavaMailProperties(properties);
        return javaMailSender;
    }
}

四、接下來編寫一個介面,我這裡叫【MailBiz】,主要是定義一些使用的方法,例如有的可以發附件,有的方法可以抄送等等

package cn.xt.app.biz.mail;

import java.util.List;

/**
 * create: xiaotian
 * date: 2018/10/20
 */
public interface MailBiz {

    void sendMail(String subject, String body, String from, String[] to) throws Exception;

    void sendMail(String subject, String body, String from, String[] cc, String[] to) throws Exception;

    void sendMail(String subject, String body, boolean html, String from, String[] cc, String[] to) throws Exception;

    void sendMail(String subject, String body, boolean html, String from, String[] cc, String[] to, List<String> attachPathList) throws Exception;
}

五、接下來定義一個實現類【MailBizService】來實現【MailBiz】這個介面

package cn.xt.app.service.mail;

import cn.xt.app.biz.mail.MailBiz;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Multipart;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.util.Date;
import java.util.List;

/**
 * create: xiaotian
 * date: 2018/10/20
 */
@Slf4j
@Service
public class MailBizService implements MailBiz {

    @Autowired
    private JavaMailSenderImpl javaMailSender;

    /**
     * 傳送郵件
     *
     * @param subject 主題
     * @param body    內容
     * @param from    發件人
     * @param to      收件人[多個]
     */
    public void sendMail(String subject, String body, String from, String[] to) throws Exception {
        sendMail(subject, body, from, null, to);
    }

    /**
     * 傳送郵件
     *
     * @param subject 主題
     * @param body    內容
     * @param from    發件人
     * @param cc      抄送人[多個]
     * @param to      收件人[多個]
     */
    public void sendMail(String subject, String body, String from, String[] cc, String[] to) throws Exception {
        sendMail(subject, body, false, from, cc, to);
    }

    /**
     * 傳送郵件
     *
     * @param subject 主題
     * @param body    內容
     * @param html    是否為html格式
     * @param from    發件人
     * @param cc      抄送人[多個]
     * @param to      收件人[多個]
     */
    public void sendMail(String subject, String body, boolean html, String from, String[] cc, String[] to) throws Exception {
        sendMail(subject, body, html, from, cc, to, null);
    }

    /**
     * 傳送郵件
     *
     * @param subject        主題
     * @param body           內容
     * @param html           是否為html格式
     * @param from           發件人
     * @param cc             抄送人[多個]
     * @param to             收件人[多個]
     * @param attachPathList 附件路徑
     */
    public void sendMail(String subject, String body, boolean html, String from, String[] cc, String[] to, List<String> attachPathList) throws Exception {
        try {
            MimeMessage parentMimeMessage = javaMailSender.createMimeMessage();
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(parentMimeMessage, true, "utf-8");
            mimeMessageHelper.setSubject(subject);
            mimeMessageHelper.setFrom(new InternetAddress(from));
            mimeMessageHelper.setSentDate(new Date());

            // 設定收件人地址
            mimeMessageHelper.setTo(to);

            // 設定抄送人
            if (!StringUtils.isEmpty(cc)) {
                mimeMessageHelper.setCc(cc);
            }

            // 設定正文
            mimeMessageHelper.setText(body, html);

            // 設定附件
            if (!CollectionUtils.isEmpty(attachPathList)) {
                Multipart multipart = new MimeMultipart();
                for (String attachPath : attachPathList) {
                    MimeBodyPart mimeBodyPart = new MimeBodyPart();
                    DataHandler dataHandler = new DataHandler(new FileDataSource(attachPath));
                    mimeBodyPart.setDataHandler(dataHandler);
                    mimeBodyPart.setFileName(dataHandler.getName());
                    multipart.addBodyPart(mimeBodyPart);
                }
                parentMimeMessage.setContent(multipart);
            }
            // 正式傳送郵件
            javaMailSender.send(parentMimeMessage);
        } catch (Exception e) {
            log.error("傳送郵件失敗:{}", e);
            throw e;
        }
    }
}

至此,傳送郵件的程式碼到這裡就這完成了,可以寫單元測試來看下效果。這些程式碼都是經過我的嚴格測試的,功能都是OK的。

我這裡傳送郵件的程式碼以供大家參考:
這裡特別指出一下:【mailFrom】也就是發件人,必須是你自己的郵箱號

@Autowired
private MailBiz mailBiz;

@Value("${mail.username}")
private String mailFrom;

@Override
public ResultResponse sendMail(SendEmailRequest request) {
    ResultResponse response = new ResultResponse();
    try {
        mailBiz.sendMail(request.getSubject(), request.getBody(), request.getHtml(), //
                mailFrom, request.getCc(), request.getTo(), request.getAttachPathList());
        response.setCode(ApplicationStatusEnum.SUCCESS.getCode());
        response.setMessage("郵件傳送成功");
    } catch (Exception e) {
        response.setCode(ApplicationStatusEnum.FAILED.getCode());
        response.setMessage("郵件傳送失敗");
    }
    return response;
}

總結:利用 yml 配置一些引數,比直接寫在程式碼裡面靈活,以 @Value 註解把配置檔案中的值注入到變數中。另外在Config中以@Bean的方式將一些配置初始化,相當於核心工作交給Spring去管理,不易出錯,且比較好維護。

程式碼中如有不足之處請大家留言指正!