详细分析Java中的发送邮件JavaMail API 以及Hutool MailUtil.send (附Demo)

前言

🤟 找工作,来万码优才:👉 #小程序://万码优才/r6rqmzDaXpYkJZF

爬虫神器,无代码爬取,就来:bright.cn

Java基本知识:

  1. java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全)
  2. 【Java项目】实战CRUD的功能整理(持续更新)

1. JavaMail API

Java 发送邮件的基本功能可以通过 JavaMail API 来实现。JavaMail 是一个 Java 提供的标准 API,用于发送电子邮件

本文主要展示不同的邮件发送方式,如单附件、多个收件人、多个附件等,来实现邮件发送功能

Java 发送邮件的基本步骤

  1. 配置邮件会话:
    设置邮件服务器的主机、端口等信息
    使用 JavaMail 提供的 Session 类创建邮件会话对象

  2. 创建邮件内容:
    使用 MimeMessage 创建邮件内容。
    设置邮件的主题、发件人、收件人、内容等

  3. 发送邮件:
    使用 Transport.send 方法来发送邮件

在这里插入图片描述
截图如下:

在这里插入图片描述

下述是单发邮件:(修改自身的数据即可)

import javax.mail.*;
import javax.mail.internet.*;
import java.util.Properties;

public class SimpleMailSender {

    public static void main(String[] args) {
        // 1. 设置邮件服务器的基本信息
        String host = "smtp.example.com"; // 邮件服务器的地址
        String port = "25"; // 邮件服务器的端口号(例如:25是常用的SMTP端口)
        String from = "sender@example.com"; // 发件人邮箱
        String to = "receiver@example.com"; // 收件人邮箱
        String username = "sender"; // 邮箱用户名
        String password = "password"; // 邮箱密码

        // 2. 设置邮件内容
        String subject = "邮件主题";
        String body = "邮件正文内容";

        // 3. 配置邮件会话(使用SSL和SMTP服务器连接)
        Properties properties = new Properties();
        properties.put("mail.smtp.host", host);
        properties.put("mail.smtp.port", port);
        properties.put("mail.smtp.auth", "true");
        // properties.put("mail.smtp.starttls.enable", "true"); // 启用TLS

        // 4. 创建会话对象并进行身份验证
        Session session = Session.getInstance(properties, new Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username, password);
            }
        });

        try {
            // 5. 创建邮件消息
            MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress(from));
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
            message.setSubject(subject);
            message.setText(body);

            // 6. 发送邮件
            Transport.send(message);

            System.out.println("邮件发送成功!");
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }
}

注意username不等于from表单,需要去除后缀

多附件的发送方式:

import javax.mail.*;
import javax.mail.internet.*;
import java.io.File;
import java.util.List;
import java.util.Arrays;
import java.util.Properties;

public class MultiMailSender {

    public static void main(String[] args) {
        // 1. 设置邮件服务器的基本信息
        String host = "smtp.example.com"; // 邮件服务器的地址
        String port = "25"; // 邮件服务器的端口号(例如:25是常用的SMTP端口)
        String from = "sender@example.com"; // 发件人邮箱
        // java11:
        //  List<String> toList = List.of("receiver1@example.com", "receiver2@example.com"); // 收件人邮箱列表
        // java 8
        List<String> toList = Arrays.asList("receiver1@example.com", "receiver2@example.com"); // 收件人邮箱列表
        String username = "sender"; // 邮箱用户名
        String password = "password"; // 邮箱密码

        // 2. 设置邮件内容
        String subject = "邮件主题";
        String body = "邮件正文内容";

        // 3. 创建附件
        File attachment1 = new File("path/to/attachment1.txt"); // 附件1
        File attachment2 = new File("path/to/attachment2.jpg"); // 附件2

        // 4. 配置邮件会话(使用SSL和SMTP服务器连接)
        Properties properties = new Properties();
        properties.put("mail.smtp.host", host);
        properties.put("mail.smtp.port", port);
        properties.put("mail.smtp.auth", "true");
        // properties.put("mail.smtp.starttls.enable", "true"); // 启用TLS

        // 5. 创建会话对象并进行身份验证
        Session session = Session.getInstance(properties, new Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username, password);
            }
        });

        try {
            // 6. 创建邮件消息
            MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress(from));

            // 设置多个收件人
            for (String to : toList) {
                message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
            }

            message.setSubject(subject);

            // 创建邮件正文
            MimeBodyPart bodyPart = new MimeBodyPart();
            bodyPart.setText(body);

            // 创建附件部分
            MimeBodyPart attachmentPart1 = new MimeBodyPart();
            attachmentPart1.attachFile(attachment1);

            MimeBodyPart attachmentPart2 = new MimeBodyPart();
            attachmentPart2.attachFile(attachment2);

            // 创建多部分邮件
            Multipart multipart = new MimeMultipart();
            multipart.addBodyPart(bodyPart);
            multipart.addBodyPart(attachmentPart1);
            multipart.addBodyPart(attachmentPart2);

            message.setContent(multipart);

            // 7. 发送邮件
            Transport.send(message);

            System.out.println("邮件发送成功!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

截图如下:

在这里插入图片描述

另外一种方式:

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import java.io.File;
import java.util.*;

public class MultiAttachmentMailSender {

    public static void main(String[] args) {
        // 邮箱服务器信息
        String host = "smtp.example.com"; // SMTP服务器地址,记得对应修改
        String port = "25"; // 此处我这边是25 // 一般587开启TLS,465开启SSL
        String username = "sender"; // 发件人邮箱
        String password = "password"; // 授权码或邮箱密码

        // 邮件信息
        String from = "sender@example.com";
        List<String> toList = Arrays.asList("receiver1@example.com", "receiver2@example.com");
        String subject = "测试多附件邮件";
        String content = "这是一个带多个附件的邮件示例";

        // 附件列表
        List<File> attachments = Arrays.asList(
                new File("C:/test/附件1.txt"),
                new File("C:/test/附件2.jpg")
        );

        // 配置SMTP属性
        Properties props = new Properties();
        props.put("mail.smtp.host", host);
        props.put("mail.smtp.port", port);
        props.put("mail.smtp.auth", "true");
        // props.put("mail.smtp.starttls.enable", "true"); // 启用TLS
        props.put("mail.debug", "true"); // 打开debug调试信息

        Session session = Session.getInstance(props, new Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username, password);
            }
        });

        try {
            MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress(from));

            // 添加多个收件人
            for (String to : toList) {
                message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
            }

            message.setSubject(subject);

            // 创建正文部分
            MimeBodyPart textPart = new MimeBodyPart();
            textPart.setText(content, "UTF-8");

            // 创建多部分邮件(正文 + 附件)
            Multipart multipart = new MimeMultipart();
            multipart.addBodyPart(textPart);

            // 添加附件部分
            for (File file : attachments) {
                if (file.exists()) {
                    MimeBodyPart attachPart = new MimeBodyPart();
                    FileDataSource source = new FileDataSource(file);
                    attachPart.setDataHandler(new DataHandler(source));
                    attachPart.setFileName(MimeUtility.encodeText(file.getName(), "UTF-8", null));
                    multipart.addBodyPart(attachPart);
                } else {
                    System.err.println("附件文件不存在: " + file.getAbsolutePath());
                }
            }

            message.setContent(multipart);
            Transport.send(message);

            System.out.println("多附件邮件发送成功!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

截图如下:
在这里插入图片描述

2. Hutool MailUtil.send

Hutool 是一个 Java 工具类库,封装了很多常用功能,包括邮件发送、日期处理、字符串处理等,使用起来更简洁

✅ MailAccount,表示一个邮件账户,类似于 JavaMail 中的 Session + Authenticator 配置组合。包含这些属性:

  • host:SMTP服务器地址

  • port:端口(一般是 25 或 465 或 587)

  • auth:是否需要认证

  • from:发件人邮箱地址

  • user/pass:发件人邮箱账户和密码

  • sslEnable/starttlsEnable:是否启用 SSL/TLS

✅ MailUtil.send(…)
核心方法有多个重载版本:

public static String send(MailAccount account, String to, String subject, String content, boolean isHtml, File... files)
  • account: 邮件账号配置

  • to: 收件人,可以是多个,逗号或分号分隔

  • subject: 邮件主题

  • content: 正文内容

  • isHtml: 是否为 HTML 格式

  • files: 附件列表,可变参数 File…

底层还是使用 JavaMail 实现的,但封装了创建 Session、构造 MimeMessage、添加附件等复杂逻辑

3. 实战

实战中以Hutool MailUtil.send为主,开源项目:芋道源码/ruoyi-vue-pro

原本开源项目是没带附件:

在这里插入图片描述

后续修改开源项目,让其可以发送多个人,多个附件:

/**
 * 执行真正的邮件发送(多附件 多个收件人)
 * 注意,该方法仅仅提供给 MQ Consumer 使用
 *
 * @param message 邮件
 */
@Override
public void doMultiSendMail(MultiMailSendMessage message) {
    // 1. 创建发送账号
    MailAccountDO account = validateMailAccount(message.getAccountId());
    MailAccount mailAccount  = MailAccountConvert.INSTANCE.convert(account, message.getNickname());
    // 2. 发送邮件
    try {
        List<File> attachments = message.getAttachments();
        List<String> mailList = message.getMails();

        // 将List<String>合并为一个以";"分隔的字符串
        String mails = String.join(";", mailList);

        // 然后按分号分割
        String[] recipientAddresses = mails.split(";");


        String messageId = MailUtil.send(
                mailAccount,
                String.join(",", recipientAddresses),
                message.getTitle(),
                message.getContent(),
                true,
                (attachments != null) ? attachments.toArray(new File[0]) : new File[0]
        );

        // 3. 更新结果(成功)
        mailLogService.updateGateMailSendResult(message.getLogId(), messageId, null);
    } catch (Exception e) {
        // 3. 更新结果(异常)
        mailLogService.updateGateMailSendResult(message.getLogId(), null, e);
    }
}

对应的方法参数:

@Data
public class MultiMailSendMessage {
    /**
     * 邮件日志编号
     */
    @NotNull(message = "邮件日志编号不能为空")
    private Long logId;
    /**
     * 接收邮件地址
     */
    @NotNull(message = "接收邮件地址不能为空")
    private List<String> mails;
    /**
     * 邮件账号编号
     */
    @NotNull(message = "邮件账号编号不能为空")
    private Long accountId;

    /**
     * 邮件发件人
     */
    private String nickname;
    /**
     * 邮件标题
     */
    @NotEmpty(message = "邮件标题不能为空")
    private String title;
    /**
     * 邮件内容
     */
    @NotEmpty(message = "邮件内容不能为空")
    private String content;

    // 新增附件字段,类型为List<File> 支持多个附件
    private List<File> attachments;

    public MultiMailSendMessage setMails(List<String> mails) {
        this.mails = mails;
        return this;
    }

    public MultiMailSendMessage setAttachments(List<File> attachments) {
        this.attachments = attachments;
        return this;
    }
}

实体类:

@TableName(value = "system_mail_account", autoResultMap = true)
@Data
@EqualsAndHashCode(callSuper = true)
public class MailAccountDO extends BaseDO {

    /**
     * 主键
     */
    @TableId
    private Long id;
    /**
     * 邮箱
     */
    private String mail;

    /**
     * 用户名
     */
    private String username;
    /**
     * 密码
     */
    private String password;
    /**
     * SMTP 服务器域名
     */
    private String host;
    /**
     * SMTP 服务器端口
     */
    private Integer port;
    /**
     * 是否开启 SSL
     */
    private Boolean sslEnable;

}

实战中的 doSendMail() 和 doMultiSendMail() 方法详解

单封邮件发送 doSendMail()

MailUtil.send(mailAccount, message.getMail(), message.getTitle(), message.getContent(), true);
  • mailAccount:从数据库或配置中读取,转换为 Hutool 的 MailAccount

  • message.getMail():收件人

  • getContent() 是 HTML 内容(true 参数表示以 HTML 格式发送)

出错时会更新日志记录错误信息(非常实用的生产实践)

多人带附件发送 doMultiSendMail()

MailUtil.send(mailAccount,
              String.join(",", recipientAddresses),
              message.getTitle(),
              message.getContent(),
              true,
              attachments.toArray(new File[0])
);
  • 支持 多个收件人

  • 支持 多个附件

  • 自动将收件人列表转换为字符串并逗号分隔

  • 对 null 附件做了处理,防止抛异常

4. 总结

三种方式对比总结

特性JavaMail 原生 (无附件)JavaMail 原生 (带附件)Hutool MailUtil
代码复杂度⭐ 低❌ 高,需构造多层 MimeMultipart✅ 极简调用
附件支持❌ 不支持✅ 支持多附件✅ 支持多附件
多人收件❌ 需循环添加 addRecipient❌ 同上✅ to 支持逗号或分号分隔
HTML支持✅ setContent(…) 手动设置✅ MimeBodyPart.setContent()✅ 通过 isHtml=true
错误处理❌ 易遗漏❌ 易遗漏✅ 结合日志服务统一封装
依赖包JavaMail APIJavaMail APIJavaMail + Hutool
使用场景简单测试正式但代码繁琐🚀 实战推荐
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农研究僧

你的鼓励将是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值