047-Java 发送邮件

Java 提供了强大的邮件发送功能,可以通过 JavaMail API 处理邮件的发送、接收和转发。以下是 Java 发送邮件的详细教程,包括基础用法、常见配置和高级场景。


1. 准备工作

1.1 添加 JavaMail 依赖

Maven 项目

在 Maven 项目的 pom.xml 文件中添加以下依赖:

<dependency>
    <groupId>com.sun.mail</groupId>
    <artifactId>javax.mail</artifactId>
    <version>1.6.2</version>
</dependency>
非 Maven 项目

如果不是 Maven 项目,可以下载以下 JAR 文件并添加到项目的 classpath


1.2 常见邮件协议

  1. SMTP (Simple Mail Transfer Protocol):用于发送邮件。
  2. IMAP (Internet Message Access Protocol):用于接收邮件。
  3. POP3 (Post Office Protocol 3):另一种接收邮件的协议。

本教程主要讲解如何通过 SMTP 发送邮件。


2. 发送邮件的基本代码

以下是发送简单邮件的标准实现。

2.1 基本示例:发送纯文本邮件

代码实现
import javax.mail.*;
import javax.mail.internet.*;
import java.util.Properties;

public class EmailSender {
    public static void main(String[] args) {
        // 发件人邮箱
        final String fromEmail = "your-email@example.com";
        // 邮箱密码或授权码(视邮箱服务商要求)
        final String password = "your-email-password";
        // 收件人邮箱
        final String toEmail = "recipient-email@example.com";

        // 配置 SMTP 服务器属性
        Properties properties = new Properties();
        properties.put("mail.smtp.host", "smtp.example.com"); // SMTP 主机名(如 Gmail: smtp.gmail.com)
        properties.put("mail.smtp.port", "587"); // SMTP 端口号
        properties.put("mail.smtp.auth", "true"); // 是否需要认证
        properties.put("mail.smtp.starttls.enable", "true"); // 启用 STARTTLS

        // 创建会话
        Session session = Session.getInstance(properties, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(fromEmail, password);
            }
        });

        try {
            // 创建邮件内容
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress(fromEmail)); // 设置发件人
            message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail)); // 设置收件人
            message.setSubject("测试邮件"); // 设置邮件主题
            message.setText("这是通过 Java 发送的测试邮件。"); // 设置邮件正文

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

2.2 配置说明

  1. SMTP 主机和端口

    • 不同邮箱服务商的 SMTP 主机名和端口不同:
      • Gmailsmtp.gmail.com,端口 587(STARTTLS)或 465(SSL)。
      • Outlook/Hotmailsmtp.office365.com,端口 587
      • QQ 邮箱smtp.qq.com,端口 587465
      • 163 邮箱smtp.163.com,端口 25465
  2. 授权码

    • 部分邮箱(如 Gmail、QQ)需要使用授权码代替密码。授权码可以在邮箱设置中获取。
  3. TLS 和 SSL

    • STARTTLS 是一种升级现有不安全连接为加密连接的方式,常用于端口 587
    • SSL 是直接建立加密连接的方式,常用于端口 465

3. 发送带附件的邮件

可以通过 MimeMultipart 类实现发送带附件的邮件。

代码实现
import javax.mail.*;
import javax.mail.internet.*;
import java.util.Properties;
import java.io.File;

public class EmailWithAttachment {
    public static void main(String[] args) {
        final String fromEmail = "your-email@example.com";
        final String password = "your-email-password";
        final String toEmail = "recipient-email@example.com";

        Properties properties = new Properties();
        properties.put("mail.smtp.host", "smtp.example.com");
        properties.put("mail.smtp.port", "587");
        properties.put("mail.smtp.auth", "true");
        properties.put("mail.smtp.starttls.enable", "true");

        Session session = Session.getInstance(properties, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(fromEmail, password);
            }
        });

        try {
            // 创建邮件内容
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress(fromEmail));
            message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail));
            message.setSubject("带附件的测试邮件");

            // 创建邮件正文
            MimeBodyPart bodyPart = new MimeBodyPart();
            bodyPart.setText("这是带附件的邮件,请查收!");

            // 创建附件部分
            MimeBodyPart attachmentPart = new MimeBodyPart();
            attachmentPart.attachFile(new File("path/to/your/file.txt")); // 替换为实际文件路径

            // 组合邮件内容
            Multipart multipart = new MimeMultipart();
            multipart.addBodyPart(bodyPart);
            multipart.addBodyPart(attachmentPart);

            // 设置邮件内容
            message.setContent(multipart);

            // 发送邮件
            Transport.send(message);
            System.out.println("带附件的邮件发送成功!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4. 发送HTML格式的邮件

可以通过 setContent 方法发送 HTML 格式的邮件。

代码实现
import javax.mail.*;
import javax.mail.internet.*;
import java.util.Properties;

public class EmailWithHTML {
    public static void main(String[] args) {
        final String fromEmail = "your-email@example.com";
        final String password = "your-email-password";
        final String toEmail = "recipient-email@example.com";

        Properties properties = new Properties();
        properties.put("mail.smtp.host", "smtp.example.com");
        properties.put("mail.smtp.port", "587");
        properties.put("mail.smtp.auth", "true");
        properties.put("mail.smtp.starttls.enable", "true");

        Session session = Session.getInstance(properties, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(fromEmail, password);
            }
        });

        try {
            // 创建邮件内容
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress(fromEmail));
            message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail));
            message.setSubject("HTML 格式测试邮件");

            // 设置 HTML 内容
            String htmlContent = "<h1 style='color:blue;'>欢迎使用 Java 发送邮件!</h1>" +
                                 "<p>这是通过 HTML 格式发送的测试邮件。</p>";
            message.setContent(htmlContent, "text/html; charset=utf-8");

            // 发送邮件
            Transport.send(message);
            System.out.println("HTML 格式的邮件发送成功!");
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }
}

5. 常见问题及解决方案

5.1 无法连接 SMTP 服务器

  • 确保使用了正确的 SMTP 主机名和端口。
  • 检查是否启用了防火墙或网络限制。
  • 如果使用 Gmail,确保启用了“低安全性应用访问”或使用 OAuth。

5.2 身份验证失败

  • 确保使用正确的邮箱账号和密码。
  • 部分服务商要求使用授权码代替密码(如 Gmail、QQ 邮箱)。

5.3 SSL/TLS 配置问题

  • 如果使用端口 465,需要添加以下配置:

    properties.put("mail.smtp.socketFactory.port", "465");
    properties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
    

5.4 邮件被标记为垃圾邮件

  • 使用真实的发件人地址。
  • 避免在邮件正文中使用敏感词(如“免费”、“优惠”等)。
  • 配置 DKIM、SPF 等邮件认证机制。

6. 总结

  1. 基本功能

    • 通过 SMTP 发送纯文本邮件、HTML 邮件和带附件的邮件。
  2. 高级功能

    • 支持多收件人、抄送(CC)、密送(BCC)。
    • 支持发送带图片和样式的邮件。
  3. 注意事项

    • 确保正确配置 SMTP 主机和端口。
    • 使用授权码或密码登录。
    • 避免触发垃圾邮件过滤机制。

JavaMail 是一个功能强大的邮件发送工具,结合 SMTP 和 MIME,可以满足绝大多数邮件发送的需求。在实际项目中,建议对邮件的异常处理和安全性进行充分考虑,以确保服务的稳定性和可靠性。


7. Java 发送邮件的高级应用

在掌握了基本的邮件发送功能之后,可以进一步探索更高级的应用场景,例如群发邮件、多附件、多线程发送邮件、嵌入图片等。


7.1 群发邮件

群发邮件可以通过在邮件中设置多个收件人 (TOCCBCC) 来实现。

代码示例:群发邮件

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

public class EmailMassSender {
    public static void main(String[] args) {
        final String fromEmail = "your-email@example.com";
        final String password = "your-email-password";

        // 多个收件人
        String[] recipients = {"recipient1@example.com", "recipient2@example.com", "recipient3@example.com"};

        Properties properties = new Properties();
        properties.put("mail.smtp.host", "smtp.example.com");
        properties.put("mail.smtp.port", "587");
        properties.put("mail.smtp.auth", "true");
        properties.put("mail.smtp.starttls.enable", "true");

        Session session = Session.getInstance(properties, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(fromEmail, password);
            }
        });

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

            // 添加所有收件人
            Address[] addresses = new Address[recipients.length];
            for (int i = 0; i < recipients.length; i++) {
                addresses[i] = new InternetAddress(recipients[i]);
            }
            message.setRecipients(Message.RecipientType.TO, addresses);

            message.setSubject("群发邮件测试");
            message.setText("这是一封群发的测试邮件。");

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

注意

  1. TOCCBCC 的区别

    • TO:直接发送给主要收件人。
    • CC(抄送):发送给次要收件人,所有收件人都能看到抄送列表。
    • BCC(密送):发送给隐秘的收件人,其他收件人不会看到密送列表。
  2. 隐私保护

    • 如果需要保护收件人隐私,建议使用 BCC

7.2 多附件邮件

可以通过向 MimeMultipart 中添加多个 MimeBodyPart 来实现多附件邮件。

代码示例:发送多附件邮件

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

public class MultiAttachmentEmail {
    public static void main(String[] args) {
        final String fromEmail = "your-email@example.com";
        final String password = "your-email-password";
        final String toEmail = "recipient@example.com";

        Properties properties = new Properties();
        properties.put("mail.smtp.host", "smtp.example.com");
        properties.put("mail.smtp.port", "587");
        properties.put("mail.smtp.auth", "true");
        properties.put("mail.smtp.starttls.enable", "true");

        Session session = Session.getInstance(properties, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(fromEmail, password);
            }
        });

        try {
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress(fromEmail));
            message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail));
            message.setSubject("多附件测试邮件");

            // 创建正文部分
            MimeBodyPart bodyPart = new MimeBodyPart();
            bodyPart.setText("这是包含多个附件的测试邮件,请查收!");

            // 创建附件 1
            MimeBodyPart attachment1 = new MimeBodyPart();
            attachment1.attachFile(new File("path/to/attachment1.txt"));

            // 创建附件 2
            MimeBodyPart attachment2 = new MimeBodyPart();
            attachment2.attachFile(new File("path/to/attachment2.jpg"));

            // 组合正文和附件
            Multipart multipart = new MimeMultipart();
            multipart.addBodyPart(bodyPart);
            multipart.addBodyPart(attachment1);
            multipart.addBodyPart(attachment2);

            message.setContent(multipart);

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

7.3 嵌入图片的 HTML 邮件

可以使用 MimeMultipartrelated 类型将图片嵌入到 HTML 邮件中。

代码示例:嵌入图片的 HTML 邮件

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

public class EmailWithEmbeddedImage {
    public static void main(String[] args) {
        final String fromEmail = "your-email@example.com";
        final String password = "your-email-password";
        final String toEmail = "recipient@example.com";

        Properties properties = new Properties();
        properties.put("mail.smtp.host", "smtp.example.com");
        properties.put("mail.smtp.port", "587");
        properties.put("mail.smtp.auth", "true");
        properties.put("mail.smtp.starttls.enable", "true");

        Session session = Session.getInstance(properties, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(fromEmail, password);
            }
        });

        try {
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress(fromEmail));
            message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail));
            message.setSubject("HTML 邮件测试");

            // 创建 HTML 部分
            MimeBodyPart htmlPart = new MimeBodyPart();
            String htmlContent = "<h1>测试嵌入图片</h1>" +
                                 "<p>这是嵌入图片的 HTML 邮件:</p>" +
                                 "<img src='cid:image1'>";
            htmlPart.setContent(htmlContent, "text/html; charset=utf-8");

            // 创建图片部分
            MimeBodyPart imagePart = new MimeBodyPart();
            imagePart.attachFile(new File("path/to/image.jpg"));
            imagePart.setContentID("<image1>");
            imagePart.setDisposition(MimeBodyPart.INLINE);

            // 组合内容
            Multipart multipart = new MimeMultipart("related");
            multipart.addBodyPart(htmlPart);
            multipart.addBodyPart(imagePart);

            message.setContent(multipart);

            Transport.send(message);
            System.out.println("嵌入图片的 HTML 邮件发送成功!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

7.4 多线程发送邮件

在需要发送大量邮件时,可以使用多线程来提高效率。

代码示例:多线程发送邮件

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

public class MultiThreadedEmailSender {
    public static void main(String[] args) {
        final String fromEmail = "your-email@example.com";
        final String password = "your-email-password";

        String[] recipients = {"recipient1@example.com", "recipient2@example.com", "recipient3@example.com"};

        for (String recipient : recipients) {
            new Thread(() -> sendEmail(fromEmail, password, recipient)).start();
        }
    }

    public static void sendEmail(String fromEmail, String password, String toEmail) {
        Properties properties = new Properties();
        properties.put("mail.smtp.host", "smtp.example.com");
        properties.put("mail.smtp.port", "587");
        properties.put("mail.smtp.auth", "true");
        properties.put("mail.smtp.starttls.enable", "true");

        Session session = Session.getInstance(properties, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(fromEmail, password);
            }
        });

        try {
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress(fromEmail));
            message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail));
            message.setSubject("多线程邮件测试");
            message.setText("这是通过多线程发送的测试邮件。");

            Transport.send(message);
            System.out.println("邮件发送成功!收件人: " + toEmail);
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }
}

8. 邮件发送的注意事项

  1. 授权码

    • 部分邮箱(如 QQ 邮箱、Gmail)需要启用 SMTP 并生成授权码,代替密码使用。
  2. 邮件服务限制

    • 一些免费邮箱(如 Gmail)对每日发送的邮件数量有上限,可考虑使用企业邮箱或专用邮件服务。
  3. 垃圾邮件防护

    • 添加合适的邮件标题和内容,避免触发垃圾邮件过滤机制。
    • 配置 SPF、DKIM 和 DMARC 等邮件认证机制。
  4. 错误处理

    • MessagingException 进行详细分类和处理,例如网络超时、身份验证失败等。

9. 总结

通过 JavaMail API,可以轻松实现以下功能:

  1. 发送纯文本、HTML 格式的邮件;
  2. 添加附件、多附件;
  3. 群发邮件(TO、CC、BCC);
  4. 嵌入图片的邮件;
  5. 使用多线程提高邮件发送效率。

在实际项目中,建议将邮件发送功能封装为工具类,并结合队列或异步任务处理邮件发送,以提高系统的并发能力和可靠性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小宝哥Code

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

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

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

打赏作者

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

抵扣说明:

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

余额充值