maven依赖:pom.xml

<dependency>
  <groupId>jakarta.mail</groupId>
  <artifactId>jakarta.mail-api</artifactId>
  <version>2.1.3</version>
</dependency>
<dependency>
  <groupId>org.eclipse.angus</groupId>
  <artifactId>jakarta.mail</artifactId>
  <version>1.0.0</version>
</dependency>

工具类代码:EmailUtils.java

package com.zzzmh.utils;

import com.sun.mail.util.MailSSLSocketFactory;
import jakarta.mail.*;
import jakarta.mail.internet.*;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Date;
import java.util.Properties;

/**
 * 网易企业邮箱工具类
 * @author zzzmh
 * @date 2024年5月21日11:39:08
 */
public class EmailUtils {
    // smtp协议一般不用改
    private static final String protocol = "smtp";
    // 这里的域名和端口根据你接入哪一家决定 我这是网易企业邮箱的
    private static final String host = "smtp.qiye.163.com";
    private static final String port = "994";
    // 这里要改成你的账户名 一般是个邮箱地址
    private static final String username = "xxx@xxx.com";
    // 这里要改成你的密码 一般在邮箱设置里
    private static final String password = "xxxxxxxxxxxxxxxx";
    // 这里改成你的邮箱发送者名称 你自己起一个就行
    private static final String personal = "xxxxxxxxxxxxxx";


    // 身份验证
    static class UserAuthenticator extends Authenticator {
        String u = null;
        String p = null;

        public UserAuthenticator(String u, String p) {
            this.u = u;
            this.p = p;
        }

        @Override
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(u, p);
        }
    }

    /** 请求参数 */
    private static Properties getProperties() throws GeneralSecurityException {
        Properties prop = new Properties();
        // 协议
        prop.setProperty("mail.transport.protocol", protocol);
        // 域名
        prop.setProperty("mail.smtp.host", host);
        // 端口
        prop.setProperty("mail.smtp.port", port);
        // 使用smtp身份验证
        prop.setProperty("mail.smtp.auth", "true");
        // 使用SSL,企业邮箱必需!
        MailSSLSocketFactory mailSSLSocketFactory = new MailSSLSocketFactory();
        mailSSLSocketFactory.setTrustAllHosts(true);
        prop.put("mail.smtp.ssl.socketFactory", mailSSLSocketFactory);
        prop.put("mail.smtp.ssl.enable", "true");
        return prop;
    }

    /** 请求消息体 */
    public static MimeMessage getMimeMessage(String subject, String content, String filePath, String fileName) throws GeneralSecurityException {
        Properties prop = getProperties();
        Session session = Session.getDefaultInstance(prop, new UserAuthenticator(username, password));
        session.setDebug(false);
        MimeMessage mimeMessage = new MimeMessage(session);
        try {
            // 发件人
            if (StringUtils.isNotBlank(personal)) {
                // 可以设置发件人的别名
                mimeMessage.setFrom(new InternetAddress(username, personal));
            } else {
                // 如果不需要就省略
                mimeMessage.setFrom(new InternetAddress(username));
            }

            // 主题
            mimeMessage.setSubject(subject);
            // 时间
            mimeMessage.setSentDate(new Date());
            // 容器类,可以包含多个MimeBodyPart对象
            Multipart mp = new MimeMultipart();

            // MimeBodyPart可以包装文本,图片,附件
            MimeBodyPart body = new MimeBodyPart();
            // HTML正文
            body.setContent(content, "text/html; charset=UTF-8");
            mp.addBodyPart(body);

            // 添加图片&附件
            if (StringUtils.isNotBlank(filePath)) {
                MimeBodyPart mbp = new MimeBodyPart();
                mbp.attachFile(filePath);
                mbp.setFileName(MimeUtility.encodeWord(fileName));
                mp.addBodyPart(mbp);
            }
            // 设置邮件内容
            mimeMessage.setContent(mp);
            mimeMessage.saveChanges();
            return mimeMessage;
        } catch (MessagingException | IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 发送邮件基本方法 (单发 含文件)
     * 需要注意的是这里发送过程会很慢大约10~20秒
     * 并且会阻塞线程,我这里就是这样设计的
     * 如果你用在接口中,建议用@Async方案做成异步处理
     */
    public static void sendEmail(String recipient, String subject, String content, String filePath, String fileName) {
        try {
            MimeMessage mimeMessage = getMimeMessage(subject, content, filePath, fileName);
            // 单个收件人
            mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(recipient));
            Transport.send(mimeMessage);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 简化版
     * @param recipient 对方邮箱地址
     * @param subject 标题
     * @param content 内容文本
     */
    public static void sendEmail(String recipient, String subject, String content) {
        sendEmail(recipient, subject, content, null, null);
    }

    public static void main(String[] args) {
       sendEmail("admin@www.codesou.cn","测试标题","测试简单文本内容");
    }
}

说明:代码是特意设计成阻塞允许的,也就是从开始执行到发送成功,大约需要20秒,如果你用在Srpingboot的Controller中,请求会长达20秒以上,一般来说必须用异步处理一下。比如在方法上标注@Async。