javax.mail邮件服务

是Java 中用于处理电子邮件的一个包,它提供了发送、接收和读取电子邮件的功能。这个包通常被称为 JavaMail API,可以用来构建需要邮件功能的应用程序。以下是一些关于 javax.mail 的关键点:

  • 功能: 支持多种邮件协议如 SMTP, POP3, IMAP 等。
  • 依赖: 你需要在项目中引入 JavaMail 库才能使用这个包中的类。
  • 主要类:
  • ------Session: 创建邮件会话,配置邮件发送的基本属性。
  • ------Message: 表示邮件内容的对象。
  • ------Transport: 用于发送消息。
  • ------Store: 用于连接邮件服务器并管理邮件存储。

如果你使用的是Maven,可以在pom.xml文件中添加以下依赖:

<dependency>
  <groupId>com.sun.mail</groupId>
  <artifactId>javax.mail</artifactId>
  <version>1.6.2</version>
</dependency>

发送邮件

import java.io.File;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

/**
 * JavaMail工具类,用于在Java中发送邮件
 *
 * @author hudy
 * @date 2024/9/14 13:41
 */
public class EmailSender {

  /**
   * 邮箱发送账号
   */
  public static String USERNAME = "hello@gmail.com";

  /**
   * 邮箱平台的授权码
   */
  public static String PASSWORD = "your password";
  /**
   * SMTP服务器地址
   */
  public static String HOST = "smtp.gmail.com";

  /**
   * SMTP服务器端口
   */
  public static String PORT = "587";

  public static Session session = null;

  /**
   * 创建邮件会话
   * <p>
   * 本方法用于初始化一个邮件会话(session),该会话配置了必要的属性以支持通过SMTP发送邮件 如果session已经初始化,则方法直接返回不做任何操作
   */
  public static void createMailSession() {
    if (session != null) {
      return;
    }

    // 设置邮件会话属性
    Properties props = new Properties();
    // 启用SMTP身份验证
    props.put("mail.smtp.auth", "true");
    // 启用STARTTLS加密 587端口
    props.put("mail.smtp.starttls.enable", "true");
    // 设置SMTP主机
    props.put("mail.smtp.host", HOST);
    // 设置SMTP端口
    props.put("mail.smtp.port", PORT);
    if ("465".equals(PORT)) {
      props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
      props.put("mail.smtp.socketFactory.fallback", "false");
      props.put("mail.smtp.socketFactory.port", "465");
    }

    // 创建邮件会话实例
    session = Session.getInstance(props,
        new javax.mail.Authenticator() {
          @Override
          protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(USERNAME, PASSWORD);
          }
        });
  }

  /**
   * 发送纯文本邮件
   *
   * @param title   邮件标题
   * @param content 邮件内容
   * @param toMail  收件人邮箱地址
   */
  public static void postMessage(String title, String content, String toMail) {
    try {
      createMailSession();
      //构造邮件主体
      MimeMessage message = new MimeMessage(session);
      message.setSubject(title);
      message.setText(content);
      message.setFrom(new InternetAddress(USERNAME));
      String[] recipients = toMail.split(",");
      for (String recipient : recipients) {
        message.addRecipient(MimeMessage.RecipientType.TO, new InternetAddress(recipient.trim()));
      }
      //发送
      Transport.send(message);
    } catch (MessagingException e) {
      if (e.getMessage().contains("554 Reject by")) {
        throw new RuntimeException("发信行为被反垃圾拦截,投递失败。");
      }
      throw new RuntimeException(e);
    }
  }

  /**
   * 发送带附件的邮件
   * <p>
   * 此方法用于发送一封带有附件的邮件,它首先创建邮件会话,然后构造邮件主体和附件,并发送邮件
   *
   * @param title       邮件标题
   * @param htmlContent 邮件内容,支持HTML格式
   * @param filePath    附件文件路径
   * @param toMail      收件人邮箱地址
   */
  public static void postMessageWithFile(String title, String htmlContent, String filePath, String toMail) {

    try {
      // 创建邮件会话
      createMailSession();

      // 构造邮件主体
      MimeMessage message = new MimeMessage(session);
      message.setSubject(title);

      // 设置邮件正文为HTML格式
      BodyPart textPart = new MimeBodyPart();
      textPart.setContent(htmlContent, "text/html;charset=utf-8");

      // 设置邮件附件
      BodyPart filePart = new MimeBodyPart();
      DataSource source = new FileDataSource(filePath);
      filePart.setFileName(new File(filePath).getName());
      filePart.setDataHandler(new DataHandler(source));

      // 将邮件正文和附件组合到多部分对象中
      Multipart multipart = new MimeMultipart();
      multipart.addBodyPart(textPart);
      multipart.addBodyPart(filePart);
      message.setContent(multipart);

      // 设置发件人和收件人
      message.setFrom(new InternetAddress(USERNAME));
      String[] recipients = toMail.split(",");
      for (String recipient : recipients) {
        message.addRecipient(MimeMessage.RecipientType.TO, new InternetAddress(recipient.trim()));
      }
      // 发送邮件
      Transport.send(message);
    } catch (Exception e) {
      // 如果有异常抛出,转换为运行时异常
      if (e.getMessage().contains("554 Reject by")) {
        throw new RuntimeException("发信行为被反垃圾拦截,投递失败。");
      }
      throw new RuntimeException(e);
    }
  }
}

读取邮件

获取邮件列表,并读取每封邮件的内容。

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

public class EmailReader {

    public static void main(String[] args) {
        String email = "your-email@example.com";
        String password = "your-password";
        String host = "imap.example.com";

        readEmails(email, password, host);
    }

    public static void readEmails(String email, String password, String host) {
        Properties props = new Properties();
        props.put("mail.imap.host", host);
        props.put("mail.imap.port", "993");
        props.put("mail.imap.auth", "true");
        props.put("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.put("mail.imap.socketFactory.fallback", "false");
        props.put("mail.imap.socketFactory.port", "993");

        Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(email, password);
            }
        });

        try {
            // 连接到邮件服务器
            Store store = session.getStore("imap");
            store.connect(host, email, password);

            // 打开 INBOX 文件夹
            Folder folder = store.getFolder("INBOX");
            folder.open(Folder.READ_ONLY);

            // 获取邮件列表
            Message[] messages = folder.getMessages();

            // 遍历邮件
            for (int i = 0; i < messages.length; i++) {
                Message message = messages[i];
                System.out.println("Message " + (i + 1) + ": " + message.getSubject());
                System.out.println("From: " + message.getFrom()[0]);
                System.out.println("Sent Date: " + message.getSentDate());
                System.out.println("Content:");

                // 获取邮件内容
                Object content = message.getContent();
                if (content instanceof Multipart) {
                    Multipart multipart = (Multipart) content;
                    for (int j = 0; j < multipart.getCount(); j++) {
                        BodyPart bodyPart = multipart.getBodyPart(j);
                        if (bodyPart.isMimeType("text/plain")) {
                            System.out.println("Text Content: " + bodyPart.getContent());
                        } else if (bodyPart.isMimeType("text/html")) {
                            System.out.println("HTML Content: " + bodyPart.getContent());
                        }
                    }
                } else if (content instanceof String) {
                    System.out.println("Content: " + content);
                }

                System.out.println("-------------------------------");
            }

            // 关闭文件夹
            folder.close(false);

            // 关闭连接
            store.close();

            System.out.println("Emails read successfully!");
        } catch (NoSuchProviderException | MessagingException | IOException e) {
            e.printStackTrace();
        }
    }
}

接收邮件

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

public class EmailReceiver {

    public static void main(String[] args) {
        String email = "your-email@example.com";
        String password = "your-password";
        String host = "imap.example.com";

        receiveEmails(email, password, host);
    }

    public static void receiveEmails(String email, String password, String host) {
        Properties props = new Properties();
        props.put("mail.imap.host", host);
        props.put("mail.imap.port", "993");
        props.put("mail.imap.auth", "true");
        props.put("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.put("mail.imap.socketFactory.fallback", "false");
        props.put("mail.imap.socketFactory.port", "993");

        Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(email, password);
            }
        });

        try {
            // 连接到邮件服务器
            Store store = session.getStore("imap");
            store.connect(host, email, password);

            // 打开 INBOX 文件夹
            Folder folder = store.getFolder("INBOX");
            folder.open(Folder.READ_ONLY);

            // 获取邮件列表
            Message[] messages = folder.getMessages();

            // 遍历邮件
            for (int i = 0; i < messages.length; i++) {
                Message message = messages[i];
                System.out.println("Message " + (i + 1) + ": " + message.getSubject());
                System.out.println("From: " + message.getFrom()[0]);
                System.out.println("Sent Date: " + message.getSentDate());
                System.out.println("Content: " + message.getContent());

                // 打印邮件正文
                Object content = message.getContent();
                if (content instanceof Multipart) {
                    Multipart multipart = (Multipart) content;
                    for (int j = 0; j < multipart.getCount(); j++) {
                        BodyPart bodyPart = multipart.getBodyPart(j);
                        if (bodyPart.isMimeType("text/plain")) {
                            System.out.println("Text Content: " + bodyPart.getContent());
                        } else if (bodyPart.isMimeType("text/html")) {
                            System.out.println("HTML Content: " + bodyPart.getContent());
                        }
                    }
                }
            }

            // 关闭文件夹
            folder.close(false);

            // 关闭连接
            store.close();

            System.out.println("Emails received successfully!");
        } catch (NoSuchProviderException | MessagingException | IOException e) {
            e.printStackTrace();
        }
    }
}

常见问题

发送邮件报554错误解决

  • 联系收件人把发件人邮箱加入到白名单
  • 文件附件包含危险脚本:如.exe可执行文件。替换为zip格式等
  • 遵守反垃圾邮件政策: 邮箱提供商通常会有反垃圾邮件策略,为了避免被识别为垃圾邮件,发送邮件时要尽量遵守这些策略。例如,避免使用敏感词汇、不要发送大型附件、避免过于频繁的发送等。

javax.mail.AuthenticationFailedException: 526 Authentication fail 

这通常是因为提供的用户名、密码或者其他认证信息不正确,或者邮件服务器配置有误。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐