javamail - 发送邮件

一. 说明

演示版本 :Spring Boot - 2.4.1

二. 添加 Maven 依赖

<!-- 邮件服务 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
    <version>2.3.7.RELEASE</version>
</dependency>

三. 创建发送邮件参数对象

@Data
@AllArgsConstructor
@NoArgsConstructor
public class SendMailDo {
    /**
     * 发件人邮箱
     */
    private String address;
    /**
     * 发件人名称
     */
    private String addressName;
    /**
     * 发件人邮箱密码
     */
    private String password;
    /**
     * 接收人邮箱
     */
    private String toMail;
    /**
     * 接收人名称
     */
    private String toMailName;
    /**
     * 主题
     */
    private String subject;
    /**
     * 正文
     */
    private String content;
}

四. 创建各家邮箱对应 Host 地址枚举

@Getter
@AllArgsConstructor
@NoArgsConstructor
public enum MailTypeEnums {
    QQ("qq", "imap.qq.com"),
    OUT_LOOK("outlook", "outlook.office365.com"),
    WANG_YI("163", "imap.163.com"),
    SINA("sohu", "imap.sohu.com"),
    SOHU("sina", "imap.sina.com"),

    ;
    private String mailType;
    private String host;

    /**
     * 根据类型取邮箱Host
     *
     * @param mailType 邮箱类型
     * @return java.lang.String
     */
    public static String getHostByType(String mailType){
        for (MailTypeEnums enums :MailTypeEnums.values()) {
            if (enums.getMailType() == mailType) {
                return enums.getHost();
            }
        }
        return "";
    }
}

五. 创建业务层

5.1 创建发送邮件Session

    /**
     * 获取发送邮件Session
     *
     * @return javax.mail.Session
     */
    public static Session getSendClient() {
        // 1. 创建一封邮件
        Properties props = new Properties(); // 用于连接邮件服务器的参数配置(发送邮件时才需要用到)
        props.put("mail.transport.protocol", "smtp");   // 使用的协议(JavaMail规范要求)
        props.put("mail.smtp.host", MailTypeEnums.OUT_LOOK.getHost());   // 发件人的邮箱的 SMTP 服务器地址
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.starttls.enable", "true");

        props.put("mail.smtp.port", "587");
        props.put("mail.smtp.socketFactory.port", "587");
        props.put("mail.smtp.socketFactory.fallback", "true");
        props.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory");
        // 根据参数配置,创建会话对象(为了发送邮件准备的)
        // 单独使用拉取时使用getDefaultInstance,否则需要使用getInstance
        Session session = Session.getInstance(props);
        session.setDebug(true);
        return session;
    }

5.2 发送文本邮件

     * 发送文本邮件
     *
     * @param sendMailDo 发件参数对象
     * @return void
     */
    public Boolean sendSimpleMail(SendMailDo sendMailDo) {
        /* 1. 校验参数 */

        // 2. 获取链接
        Session sendClient = getSendClient();
        // 3. 获取邮件
        MimeMessage mimeMessage = establishMessage(sendMailDo, sendClient);

        try {
            // 4. 根据 Session 获取邮件传输对象
            Transport transport = sendClient.getTransport();
            // 4.1 设置发件箱和密码
            transport.connect(sendMailDo.getAddress(), sendMailDo.getPassword());
            // 4.2 发送邮件, 发到所有的收件地址, message.getAllRecipients() 获取到的是在创建邮件对象时添加的所有收件人, 抄送人, 密送人
            transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
            // 4.3 关闭连接
            transport.close();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

5.3 创建邮件对象

    /**
     * 创建邮件对象
     *
     * @param sendMailDo 发送邮件参数, session
     * @return javax.mail.internet.MimeMessage
     */
    public static MimeMessage establishMessage(SendMailDo sendMailDo, Session session) {
        // 创建邮件对象
        MimeMessage message = new MimeMessage(session);
        try {
            // From: 发件人
            message.setFrom(new InternetAddress(sendMailDo.getAddress(), sendMailDo.getAddressName(), "UTF-8"));
            // To: 收件人
            message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(sendMailDo.getToMail(), sendMailDo.getToMailName(), "UTF-8"));
            // Subject: 邮件主题
            message.setSubject(sendMailDo.getSubject(), "UTF-8");
            // Content: 邮件正文
            message.setText(sendMailDo.getContent());
            // 设置显示的发件时间
            message.setSentDate(new Date());
            // 保存前面的设置
            message.saveChanges();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return message;
    }

六. Controller层测试调用

@RestController
public class SendMailController {
    @Resource
    SendMailServiceImpl sendMailService;

    /**
     * 发送邮件
     *
     * @param sendMailDo 发送信息对象,切记参数不可为空
     * @return java.lang.Boolean
     */
    @PostMapping("SendMailServiceImpl")
    public Boolean SendMailServiceImpl(@RequestBody SendMailDo sendMailDo){
        return sendMailService.sendSimpleMail(sendMailDo);
    }
}