JavaMail API 快速指南



JavaMail API 提供了一个平台无关且协议无关的框架,用于构建邮件和消息应用程序。JavaMail API 提供了一组抽象类,定义了构成邮件系统的对象。它是一个可选的包(标准扩展),用于读取、撰写和发送电子邮件。

JavaMail 提供了用于构建消息系统接口的元素,包括系统组件和接口。虽然此规范未定义任何特定实现,但 JavaMail确实包含几个实现 RFC822 和 MIME 互联网消息标准的类。这些类作为 JavaMail 类包的一部分交付。

以下是 JavaMail API 支持的一些协议:

  • SMTP简单邮件传输协议的首字母缩写。它提供了一种传递电子邮件的机制。

  • POP邮局协议的首字母缩写。POP 是互联网上大多数人用于获取邮件的机制。它定义了对每个用户单个邮箱的支持。RFC 1939 定义了此协议。

  • IMAP互联网消息访问协议的首字母缩写。它是一种高级的接收邮件协议。除了邮箱可以被多个用户共享之外,它还为每个用户提供多个邮箱的支持。它在 RFC 2060 中定义。

  • MIME多用途互联网邮件扩展的首字母缩写。它不是邮件传输协议。相反,它定义了传输内容:消息、附件等的格式。这里有很多不同的文档生效:RFC 822、RFC 2045、RFC 2046 和 RFC 2047。作为 JavaMail API 的用户,您通常不必担心这些格式。但是,这些格式确实存在并被您的程序使用。

  • NNTP 及其他:许多协议由第三方提供商提供。其中一些是网络新闻传输协议 (NNTP)、安全多用途互联网邮件扩展 (S/MIME) 等。

这些细节将在后续章节中介绍。

架构

如上所述,Java 应用程序使用 JavaMail API 来撰写、发送和接收电子邮件。下图说明了 JavaMail 的架构。

JavaMail API Architecture

JavaMail API 的抽象机制类似于其他 J2EE API,例如 JDBC、JNDI 和 JMS。如上图所示,JavaMail API 分为两个主要部分:

  • 应用程序无关部分:应用程序组件使用应用程序编程接口 (API) 来发送和接收邮件消息,而与底层提供商或使用的协议无关。

  • 服务相关部分:服务提供商接口 (SPI) 使用特定于协议的语言,例如 SMTP、POP、IMAP 和网络新闻传输协议 (NNTP)。它用于将电子邮件服务的提供商插入到 J2EE 平台。

环境设置

使用您的 Java 应用程序发送电子邮件很简单,但首先您应该在您的机器上安装JavaMail APIJava Activation Framework (JAF)

仅当您不使用 Java SE 6 或更高版本时,才需要提供javax.activation 包的JavaBeans Activation Framework (JAF) 扩展。

下载并解压缩这些文件,在新建的顶级目录中,您将找到这两个应用程序的许多 jar 文件。您需要将mail.jaractivation.jar 文件添加到您的 CLASSPATH 中。

SMTP 服务器

要发送电子邮件,您必须拥有负责发送邮件的 SMTP 服务器。您可以使用以下技术之一来获取 SMTP 服务器:

  • 安装并使用任何 SMTP 服务器,例如 Postfix 服务器(适用于 Ubuntu)、Apache James 服务器(Java Apache Mail Enterprise Server)等。(或)

  • 使用主机提供商提供的 SMTP 服务器,例如:JangoSMTP 网站提供的免费 SMTP 是relay.jangosmtp.net(或)

  • 使用公司提供的 SMTP 服务器,例如 gmail、yahoo 等。

在后续章节的示例中,我们使用了免费的 JangoSMTP 服务器来发送电子邮件。您可以访问此网站创建一个帐户并配置您的电子邮件地址。

核心类

JavaMail API 包含一些用于发送、读取和删除电子邮件消息的接口和类。虽然 JavaMail API 中有很多包,但我们将介绍 Java Mail API 中经常使用的两个主要包:javax.mailjavax.mail.internet 包。这些包包含所有 JavaMail 核心类。它们是:

描述
javax.mail.SessionAPI 的关键类。一个多线程对象代表连接工厂。
javax.mail.Message一个抽象类,它模拟电子邮件消息。子类提供实际的实现。
javax.mail.Address一个抽象类,它模拟消息中的地址(发件人和收件人地址)。子类提供具体的实现。
javax.mail.Authenticator一个抽象类,用于保护邮件服务器上的邮件资源。
javax.mail.Transport一个抽象类,它模拟用于发送电子邮件消息的消息传输机制。
javax.mail.Store一个抽象类,它模拟邮件存储及其访问协议,用于存储和检索邮件。Store 分为文件夹。
javax.mail.Folder一个抽象类,代表邮件消息的文件夹。它可以包含子文件夹。
javax.mail.internet.MimeMessageMessage 是一个抽象类,因此必须使用子类;在大多数情况下,您将使用 MimeMessage。MimeMessage 是一种了解 MIME 类型和标头的电子邮件消息。
javax.mail.internet.InternetAddress此类使用 RFC822 的语法表示 Internet 电子邮件地址。典型的地址语法形式为[email protected]个人姓名 <[email protected]>

发送简单的电子邮件

这是一个发送简单电子邮件的示例。在这里,我们使用了 JangoSMTP 服务器,通过它将电子邮件发送到我们的目标电子邮件地址。“环境设置”章节解释了设置。

发送简单的电子邮件步骤如下:

  • 获取会话

  • 创建一个默认的 MimeMessage 对象,并在消息中设置发件人、收件人、主题

  • 将实际消息设置为:

    message.setText("your text goes here");
    
  • 使用 Transport 对象发送消息。

创建 Java 类

创建一个名为SendEmail 的 Java 类文件,其内容如下:

package com.tutorialspoint;

import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class SendEmail {
   public static void main(String[] args) {
      // Recipient's email ID needs to be mentioned.
      String to = "[email protected]";

      // Sender's email ID needs to be mentioned
      String from = "[email protected]";
      final String username = "manishaspatil";//change accordingly
      final String password = "******";//change accordingly

      // Assuming you are sending email through relay.jangosmtp.net
      String host = "relay.jangosmtp.net";

      Properties props = new Properties();
      props.put("mail.smtp.auth", "true");
      props.put("mail.smtp.starttls.enable", "true");
      props.put("mail.smtp.host", host);
      props.put("mail.smtp.port", "25");

      // Get the Session object.
      Session session = Session.getInstance(props,
         new javax.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
               return new PasswordAuthentication(username, password);
	   }
         });

      try {
	   // Create a default MimeMessage object.
	   Message message = new MimeMessage(session);
	
	   // Set From: header field of the header.
	   message.setFrom(new InternetAddress(from));
	
	   // Set To: header field of the header.
	   message.setRecipients(Message.RecipientType.TO,
               InternetAddress.parse(to));
	
	   // Set Subject: header field
	   message.setSubject("Testing Subject");
	
	   // Now set the actual message
	   message.setText("Hello, this is sample for to check send " +
		"email using JavaMailAPI ");

	   // Send message
	   Transport.send(message);

	   System.out.println("Sent message successfully....");

      } catch (MessagingException e) {
         throw new RuntimeException(e);
      }
   }
}

由于我们使用的是主机提供商 JangoSMTP 提供的 SMTP 服务器,因此我们需要验证用户名和密码。javax.mail.PasswordAuthentication 类用于验证密码。

编译和运行

现在我们的类已准备就绪,让我们编译上面的类。我已经将 SendEmail.java 类保存到目录:/home/manisha/JavaMailAPIExercise。我们需要在类路径中使用 jar 文件javax.mail.jaractivation.jar。执行以下命令从命令提示符编译该类(这两个 jar 文件都放在 /home/manisha/ 目录中):

javac -cp /home/manisha/activation.jar:/home/manisha/javax.mail.jar: SendEmail.java

现在类已编译,执行以下命令运行:

java -cp /home/manisha/activation.jar:/home/manisha/javax.mail.jar: SendEmail

验证输出

您应该在命令控制台中看到以下消息:

Sent message successfully....

由于我通过 JangoSMTP 向我的 gmail 地址发送电子邮件,因此我的 gmail 帐户收件箱将收到以下邮件:

JavaMail API Send Email

发送带有附件的电子邮件

这是一个从您的机器发送带有附件的电子邮件的示例。本地机器上的文件是file.txt,位于/home/manisha/。在这里,我们使用了 JangoSMTP 服务器,通过它将电子邮件发送到我们的目标电子邮件地址。“环境设置”章节解释了设置。

要发送包含内联图像的电子邮件,请按照以下步骤操作:

  • 获取会话

  • 创建一个默认的 MimeMessage 对象,并在消息中设置发件人、收件人、主题

  • 将实际消息设置为如下所示:

    messageBodyPart.setText("This is message body");
    
  • 创建一个 MimeMultipart 对象。将上面设置了实际消息的 messageBodyPart 添加到此多部分对象。

  • 接下来,通过创建 Datahandler 添加附件,如下所示:

    messageBodyPart = new MimeBodyPart();
    String filename = "/home/manisha/file.txt";
    DataSource source = new FileDataSource(filename);
    messageBodyPart.setDataHandler(new DataHandler(source));
    messageBodyPart.setFileName(filename);
    multipart.addBodyPart(messageBodyPart);
    
  • 接下来,如下所示在消息中设置多部分:

    message.setContent(multipart);
    
  • 使用 Transport 对象发送消息。

创建 Java 类

创建一个名为SendAttachmentInEmail 的 Java 类文件,其内容如下:

package com.tutorialspoint;

import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.Message;
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;

public class SendAttachmentInEmail {
   public static void main(String[] args) {
      // Recipient's email ID needs to be mentioned.
      String to = "[email protected]";

      // Sender's email ID needs to be mentioned
      String from = "[email protected]";

      final String username = "manishaspatil";//change accordingly
      final String password = "******";//change accordingly

      // Assuming you are sending email through relay.jangosmtp.net
      String host = "relay.jangosmtp.net";

      Properties props = new Properties();
      props.put("mail.smtp.auth", "true");
      props.put("mail.smtp.starttls.enable", "true");
      props.put("mail.smtp.host", host);
      props.put("mail.smtp.port", "25");

      // Get the Session object.
      Session session = Session.getInstance(props,
         new javax.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
               return new PasswordAuthentication(username, password);
            }
         });

      try {
         // Create a default MimeMessage object.
         Message message = new MimeMessage(session);

         // Set From: header field of the header.
         message.setFrom(new InternetAddress(from));

         // Set To: header field of the header.
         message.setRecipients(Message.RecipientType.TO,
            InternetAddress.parse(to));

         // Set Subject: header field
         message.setSubject("Testing Subject");

         // Create the message part
         BodyPart messageBodyPart = new MimeBodyPart();

         // Now set the actual message
         messageBodyPart.setText("This is message body");

         // Create a multipar message
         Multipart multipart = new MimeMultipart();

         // Set text message part
         multipart.addBodyPart(messageBodyPart);

         // Part two is attachment
         messageBodyPart = new MimeBodyPart();
         String filename = "/home/manisha/file.txt";
         DataSource source = new FileDataSource(filename);
         messageBodyPart.setDataHandler(new DataHandler(source));
         messageBodyPart.setFileName(filename);
         multipart.addBodyPart(messageBodyPart);

         // Send the complete message parts
         message.setContent(multipart);

         // Send message
         Transport.send(message);

         System.out.println("Sent message successfully....");
  
      } catch (MessagingException e) {
         throw new RuntimeException(e);
      }
   }
}

由于我们使用的是主机提供商 JangoSMTP 提供的 SMTP 服务器,因此我们需要验证用户名和密码。javax.mail.PasswordAuthentication 类用于验证密码。

编译和运行

现在我们的类已准备就绪,让我们编译上面的类。我已经将 SendAttachmentInEmail.java 类保存到目录:/home/manisha/JavaMailAPIExercise。我们需要在类路径中使用 jar 文件javax.mail.jaractivation.jar。执行以下命令从命令提示符编译该类(这两个 jar 文件都放在 /home/manisha/ 目录中):

javac -cp /home/manisha/activation.jar:/home/manisha/javax.mail.jar: SendAttachmentInEmail.java

现在类已编译,执行以下命令运行:

java -cp /home/manisha/activation.jar:/home/manisha/javax.mail.jar: SendAttachmentInEmail

验证输出

您应该在命令控制台中看到以下消息:

Sent message successfully....

由于我通过 JangoSMTP 向我的 gmail 地址发送电子邮件,因此我的 gmail 帐户收件箱将收到以下邮件:

JavaMail API Send Email With Attachment

发送 HTML 电子邮件

这是一个从您的机器发送 HTML 电子邮件的示例。在这里,我们使用了 JangoSMTP 服务器,通过它将电子邮件发送到我们的目标电子邮件地址。“环境设置”章节解释了设置。

此示例与发送简单电子邮件非常相似,不同之处在于,这里我们使用 setContent() 方法来设置内容,其第二个参数是“text/html”,用于指定消息中包含 HTML 内容。使用此示例,您可以发送任意大小的 HTML 内容。

要发送包含 HTML 内容的电子邮件,请按照以下步骤操作:

  • 获取会话

  • 创建一个默认的 MimeMessage 对象,并在消息中设置发件人、收件人、主题

  • 使用 setContent() 方法将实际消息设置为如下所示:

    message.setContent("<h1>This is actual message embedded in 
       HTML tags</h1>", "text/html");
    
  • 使用 Transport 对象发送消息。

创建 Java 类

创建一个名为SendHTMLEmail 的 Java 类文件,其内容如下:

package com.tutorialspoint;

import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class SendHTMLEmail {
   public static void main(String[] args) {
      // Recipient's email ID needs to be mentioned.
      String to = "[email protected]";

      // Sender's email ID needs to be mentioned
      String from = "[email protected]";
      final String username = "manishaspatil";//change accordingly
      final String password = "******";//change accordingly

      // Assuming you are sending email through relay.jangosmtp.net
      String host = "relay.jangosmtp.net";

      Properties props = new Properties();
      props.put("mail.smtp.auth", "true");
      props.put("mail.smtp.starttls.enable", "true");
      props.put("mail.smtp.host", host);
      props.put("mail.smtp.port", "25");

      // Get the Session object.
      Session session = Session.getInstance(props,
         new javax.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
               return new PasswordAuthentication(username, password);
            }
	});

      try {
            // Create a default MimeMessage object.
            Message message = new MimeMessage(session);

   	   // Set From: header field of the header.
	   message.setFrom(new InternetAddress(from));

	   // Set To: header field of the header.
	   message.setRecipients(Message.RecipientType.TO,
              InternetAddress.parse(to));

	   // Set Subject: header field
	   message.setSubject("Testing Subject");

	   // Send the actual HTML message, as big as you like
	   message.setContent(
              "<h1>This is actual message embedded in HTML tags</h1>",
             "text/html");

	   // Send message
	   Transport.send(message);

	   System.out.println("Sent message successfully....");

      } catch (MessagingException e) {
	   e.printStackTrace();
	   throw new RuntimeException(e);
      }
   }
}

由于我们使用的是主机提供商 JangoSMTP 提供的 SMTP 服务器,因此我们需要验证用户名和密码。javax.mail.PasswordAuthentication 类用于验证密码。

编译和运行

现在我们的类已经准备好了,让我们编译上面的类。我已经将SendHTMLEmail.java类保存到目录:/home/manisha/JavaMailAPIExercise。我们需要将javax.mail.jaractivation.jar这两个jar包添加到类路径中。从命令提示符执行以下命令来编译类(这两个jar包都放在/home/manisha/目录下)

javac -cp /home/manisha/activation.jar:/home/manisha/javax.mail.jar: SendHTMLEmail.java

现在类已编译,执行以下命令运行:

java -cp /home/manisha/activation.jar:/home/manisha/javax.mail.jar: SendHTMLEmail

验证输出

您应该在命令控制台中看到以下消息:

Sent message successfully....

由于我通过 JangoSMTP 向我的 gmail 地址发送电子邮件,因此我的 gmail 帐户收件箱将收到以下邮件:

JavaMail API Send HTML Email

发送包含内嵌图片的邮件

这是一个从您的机器发送包含内嵌图片的HTML邮件的示例。这里我们使用了JangoSMTP服务器来发送邮件到我们的目标邮箱地址。设置方法在环境设置章节中解释。

要发送包含内联图像的电子邮件,请按照以下步骤操作:

  • 获取会话

  • 创建一个默认的 MimeMessage 对象,并在消息中设置发件人、收件人、主题

  • 创建一个MimeMultipart对象。

  • 在我们的示例中,邮件将包含HTML部分和一个图片。所以首先创建HTML内容,并将其设置为多部件对象,如下所示:

    // first part (the html)
    BodyPart messageBodyPart = new MimeBodyPart();
    String htmlText = "<H1>Hello</H1><img src=\"cid:image\">";
    messageBodyPart.setContent(htmlText, "text/html");
    // add it
    multipart.addBodyPart(messageBodyPart);
    
  • 接下来,通过创建Datahandler添加图片,如下所示:

    // second part (the image)
    messageBodyPart = new MimeBodyPart();
    DataSource fds = new FileDataSource(
     "/home/manisha/javamail-mini-logo.png");
    
    messageBodyPart.setDataHandler(new DataHandler(fds));
    messageBodyPart.setHeader("Content-ID", "<image>");
    
  • 接下来,如下所示在消息中设置多部分:

    message.setContent(multipart);
    
  • 使用 Transport 对象发送消息。

创建 Java 类

创建一个名为SendInlineImagesInEmail的java类文件,其内容如下:

package com.tutorialspoint;

import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
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;

public class SendInlineImagesInEmail {
   public static void main(String[] args) {
      // Recipient's email ID needs to be mentioned.
      String to = "[email protected]";

      // Sender's email ID needs to be mentioned
      String from = "[email protected]";
      final String username = "manishaspatil";//change accordingly
      final String password = "******";//change accordingly

      // Assuming you are sending email through relay.jangosmtp.net
      String host = "relay.jangosmtp.net";

      Properties props = new Properties();
      props.put("mail.smtp.auth", "true");
      props.put("mail.smtp.starttls.enable", "true");
      props.put("mail.smtp.host", host);
      props.put("mail.smtp.port", "25");

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

      try {

         // Create a default MimeMessage object.
         Message message = new MimeMessage(session);

         // Set From: header field of the header.
         message.setFrom(new InternetAddress(from));

         // Set To: header field of the header.
         message.setRecipients(Message.RecipientType.TO,
            InternetAddress.parse(to));

         // Set Subject: header field
         message.setSubject("Testing Subject");

         // This mail has 2 part, the BODY and the embedded image
         MimeMultipart multipart = new MimeMultipart("related");

         // first part (the html)
         BodyPart messageBodyPart = new MimeBodyPart();
         String htmlText = "<H1>Hello</H1><img src=\"cid:image\">";
         messageBodyPart.setContent(htmlText, "text/html");
         // add it
         multipart.addBodyPart(messageBodyPart);

         // second part (the image)
         messageBodyPart = new MimeBodyPart();
         DataSource fds = new FileDataSource(
            "/home/manisha/javamail-mini-logo.png");

         messageBodyPart.setDataHandler(new DataHandler(fds));
         messageBodyPart.setHeader("Content-ID", "<image>");

         // add image to the multipart
         multipart.addBodyPart(messageBodyPart);

         // put everything together
         message.setContent(multipart);
         // Send message
         Transport.send(message);

         System.out.println("Sent message successfully....");

      } catch (MessagingException e) {
         throw new RuntimeException(e);
      }
   }
}

由于我们使用的是主机提供商 JangoSMTP 提供的 SMTP 服务器,因此我们需要验证用户名和密码。javax.mail.PasswordAuthentication 类用于验证密码。

编译和运行

现在我们的类已经准备好了,让我们编译上面的类。我已经将SendInlineImagesInEmail.java类保存到目录:/home/manisha/JavaMailAPIExercise。我们需要将javax.mail.jaractivation.jar这两个jar包添加到类路径中。从命令提示符执行以下命令来编译类(这两个jar包都放在/home/manisha/目录下)

javac -cp /home/manisha/activation.jar:/home/manisha/javax.mail.jar: SendInlineImagesInEmail.java

现在类已编译,执行以下命令运行:

java -cp /home/manisha/activation.jar:/home/manisha/javax.mail.jar: SendInlineImagesInEmail

验证输出

您应该在命令控制台中看到以下消息:

Sent message successfully....

由于我通过 JangoSMTP 向我的 gmail 地址发送电子邮件,因此我的 gmail 帐户收件箱将收到以下邮件:

JavaMail API Send Email With Inline Images

检查邮件

在继续本章之前,需要理解两个方面。它们是检查获取

  • 在JavaMail中检查邮件是一个过程,我们打开邮箱中的相应文件夹并获取每封邮件。这里我们只检查每封邮件的头部,即发件人、收件人、主题。不读取内容。

  • 在JavaMail中获取邮件是一个过程,我们打开邮箱中的相应文件夹并获取每封邮件。除了头部,我们还通过识别内容类型来读取内容。

要使用JavaMail API检查或获取邮件,我们需要POP或IMAP服务器。要检查和获取邮件,需要Folder和Store类。这里我们使用了Gmail的POP3服务器(pop.gmail.com)。本章将学习如何使用JavaMail API检查邮件。获取将在后续章节中介绍。要检查邮件:

  • 获取会话

  • 创建pop3 Store对象并连接到pop服务器。

  • 创建文件夹对象。打开邮箱中的相应文件夹。

  • 获取您的邮件。

  • 关闭Store和Folder对象。

创建 Java 类

创建一个名为CheckingMails的java类文件,其内容如下:

package com.tutorialspoint;

import java.util.Properties;

import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Store;

public class CheckingMails {

   public static void check(String host, String storeType, String user,
      String password) 
   {
      try {

      //create properties field
      Properties properties = new Properties();

      properties.put("mail.pop3.host", host);
      properties.put("mail.pop3.port", "995");
      properties.put("mail.pop3.starttls.enable", "true");
      Session emailSession = Session.getDefaultInstance(properties);
  
      //create the POP3 store object and connect with the pop server
      Store store = emailSession.getStore("pop3s");

      store.connect(host, user, password);

      //create the folder object and open it
      Folder emailFolder = store.getFolder("INBOX");
      emailFolder.open(Folder.READ_ONLY);

      // retrieve the messages from the folder in an array and print it
      Message[] messages = emailFolder.getMessages();
      System.out.println("messages.length---" + messages.length);

      for (int i = 0, n = messages.length; i < n; i++) {
         Message message = messages[i];
         System.out.println("---------------------------------");
         System.out.println("Email Number " + (i + 1));
         System.out.println("Subject: " + message.getSubject());
         System.out.println("From: " + message.getFrom()[0]);
         System.out.println("Text: " + message.getContent().toString());

      }

      //close the store and folder objects
      emailFolder.close(false);
      store.close();

      } catch (NoSuchProviderException e) {
         e.printStackTrace();
      } catch (MessagingException e) {
         e.printStackTrace();
      } catch (Exception e) {
         e.printStackTrace();
      }
   }

   public static void main(String[] args) {

      String host = "pop.gmail.com";// change accordingly
      String mailStoreType = "pop3";
      String username = "[email protected]";// change accordingly
      String password = "*****";// change accordingly

      check(host, mailStoreType, username, password);

   }

}

编译和运行

现在我们的类已经准备好了,让我们编译上面的类。我已经将CheckingMails.java类保存到目录:/home/manisha/JavaMailAPIExercise。我们需要将javax.mail.jaractivation.jar这两个jar包添加到类路径中。从命令提示符执行以下命令来编译类(这两个jar包都放在/home/manisha/目录下)

javac -cp /home/manisha/activation.jar:/home/manisha/javax.mail.jar: CheckingMails.java

现在类已编译,执行以下命令运行:

java -cp /home/manisha/activation.jar:/home/manisha/javax.mail.jar: CheckingMails

验证输出

您应该在命令控制台中看到以下消息:

messages.length---4
---------------------------------
Email Number 1
Subject: Test Mail--Fetch
From: <[email protected]>
Text: javax.mail.internet.MimeMultipart@327a5b7f
---------------------------------
Email Number 2
Subject: testing ----checking simple email
From: <[email protected]>
Text: javax.mail.internet.MimeMultipart@7f0d08bc
---------------------------------
Email Number 3
Subject: Email with attachment
From: <[email protected]>
Text: javax.mail.internet.MimeMultipart@30b8afce
---------------------------------
Email Number 4
Subject: Email with Inline image
From: <[email protected]>
Text: javax.mail.internet.MimeMultipart@2d1e165f

这里我们打印了收件箱中的邮件数量,在本例中为4。我们还打印了每封邮件的主题、发件人地址和正文。

获取邮件

在上一章中,我们学习了如何检查邮件。现在让我们看看如何获取每封邮件并读取其内容。让我们编写一个名为FetchingEmail的Java类,它将读取以下类型的邮件:

  • 简单的邮件

  • 带有附件的邮件

  • 带有内嵌图片的邮件

代码中遵循的基本步骤如下:

  • 获取Session对象。

  • 创建POP3 store对象并连接到store。

  • 创建Folder对象并打开邮箱中的相应文件夹。

  • 检索邮件。

  • 分别关闭folder和store对象。

创建 Java 类

创建一个名为FetchingEmail的java类文件,其内容如下:

package com.tutorialspoint;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.Properties;

import javax.mail.Address;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.NoSuchProviderException;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.Store;

public class FetchingEmail {

   public static void fetch(String pop3Host, String storeType, String user,
      String password) {
      try {
         // create properties field
         Properties properties = new Properties();
         properties.put("mail.store.protocol", "pop3");
         properties.put("mail.pop3.host", pop3Host);
         properties.put("mail.pop3.port", "995");
         properties.put("mail.pop3.starttls.enable", "true");
         Session emailSession = Session.getDefaultInstance(properties);
         // emailSession.setDebug(true);

         // create the POP3 store object and connect with the pop server
         Store store = emailSession.getStore("pop3s");

         store.connect(pop3Host, user, password);

         // create the folder object and open it
         Folder emailFolder = store.getFolder("INBOX");
         emailFolder.open(Folder.READ_ONLY);

         BufferedReader reader = new BufferedReader(new InputStreamReader(
	      System.in));

         // retrieve the messages from the folder in an array and print it
         Message[] messages = emailFolder.getMessages();
         System.out.println("messages.length---" + messages.length);

         for (int i = 0; i < messages.length; i++) {
            Message message = messages[i];
            System.out.println("---------------------------------");
            writePart(message);
            String line = reader.readLine();
            if ("YES".equals(line)) {
               message.writeTo(System.out);
            } else if ("QUIT".equals(line)) {
               break;
            }
         }

         // close the store and folder objects
         emailFolder.close(false);
         store.close();

      } catch (NoSuchProviderException e) {
         e.printStackTrace();
      } catch (MessagingException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      } catch (Exception e) {
         e.printStackTrace();
      }
}

   public static void main(String[] args) {

      String host = "pop.gmail.com";// change accordingly
      String mailStoreType = "pop3";
      String username = 
         "[email protected]";// change accordingly
      String password = "*****";// change accordingly

      //Call method fetch
      fetch(host, mailStoreType, username, password);

   }

   /*
   * This method checks for content-type 
   * based on which, it processes and
   * fetches the content of the message
   */
   public static void writePart(Part p) throws Exception {
      if (p instanceof Message)
         //Call methos writeEnvelope
         writeEnvelope((Message) p);

      System.out.println("----------------------------");
      System.out.println("CONTENT-TYPE: " + p.getContentType());

      //check if the content is plain text
      if (p.isMimeType("text/plain")) {
         System.out.println("This is plain text");
         System.out.println("---------------------------");
         System.out.println((String) p.getContent());
      } 
      //check if the content has attachment
      else if (p.isMimeType("multipart/*")) {
         System.out.println("This is a Multipart");
         System.out.println("---------------------------");
         Multipart mp = (Multipart) p.getContent();
         int count = mp.getCount();
         for (int i = 0; i < count; i++)
            writePart(mp.getBodyPart(i));
      } 
      //check if the content is a nested message
      else if (p.isMimeType("message/rfc822")) {
         System.out.println("This is a Nested Message");
         System.out.println("---------------------------");
         writePart((Part) p.getContent());
      } 
      //check if the content is an inline image
      else if (p.isMimeType("image/jpeg")) {
         System.out.println("--------> image/jpeg");
         Object o = p.getContent();

         InputStream x = (InputStream) o;
         // Construct the required byte array
         System.out.println("x.length = " + x.available());
         int i = 0;
         byte[] bArray = new byte[x.available()];

         while ((i = (int) ((InputStream) x).available()) > 0) {
            int result = (int) (((InputStream) x).read(bArray));
            if (result == -1)
            break;
         }
         FileOutputStream f2 = new FileOutputStream("/tmp/image.jpg");
         f2.write(bArray);
      } 
      else if (p.getContentType().contains("image/")) {
         System.out.println("content type" + p.getContentType());
         File f = new File("image" + new Date().getTime() + ".jpg");
         DataOutputStream output = new DataOutputStream(
            new BufferedOutputStream(new FileOutputStream(f)));
            com.sun.mail.util.BASE64DecoderStream test = 
                 (com.sun.mail.util.BASE64DecoderStream) p
                  .getContent();
         byte[] buffer = new byte[1024];
         int bytesRead;
         while ((bytesRead = test.read(buffer)) != -1) {
            output.write(buffer, 0, bytesRead);
         }
      } 
      else {
         Object o = p.getContent();
         if (o instanceof String) {
            System.out.println("This is a string");
            System.out.println("---------------------------");
            System.out.println((String) o);
         } 
         else if (o instanceof InputStream) {
            System.out.println("This is just an input stream");
            System.out.println("---------------------------");
            InputStream is = (InputStream) o;
            is = (InputStream) o;
            int c;
            while ((c = is.read()) != -1)
               System.out.write(c);
         } 
         else {
            System.out.println("This is an unknown type");
            System.out.println("---------------------------");
            System.out.println(o.toString());
         }
   }

}
   /*
   * This method would print FROM,TO and SUBJECT of the message
   */
   public static void writeEnvelope(Message m) throws Exception {
      System.out.println("This is the message envelope");
      System.out.println("---------------------------");
      Address[] a;

      // FROM
      if ((a = m.getFrom()) != null) {
         for (int j = 0; j < a.length; j++)
         System.out.println("FROM: " + a[j].toString());
      }

      // TO
      if ((a = m.getRecipients(Message.RecipientType.TO)) != null) {
         for (int j = 0; j < a.length; j++)
         System.out.println("TO: " + a[j].toString());
      }

      // SUBJECT
      if (m.getSubject() != null)
         System.out.println("SUBJECT: " + m.getSubject());

   }

}
您可以通过取消注释语句emailSession.setDebug(true);来启用调试。

编译和运行

现在我们的类已经准备好了,让我们编译上面的类。我已经将FetchingEmail.java类保存到目录:/home/manisha/JavaMailAPIExercise。我们需要将javax.mail.jaractivation.jar这两个jar包添加到类路径中。从命令提示符执行以下命令来编译类(这两个jar包都放在/home/manisha/目录下)

javac -cp /home/manisha/activation.jar:/home/manisha/javax.mail.jar: FetchingEmail.java

现在类已编译,执行以下命令运行:

java -cp /home/manisha/activation.jar:/home/manisha/javax.mail.jar: FetchingEmail

验证输出

您应该在命令控制台中看到以下消息:

messages.length---3
---------------------------------
This is the message envelope
---------------------------
FROM: XYZ <[email protected]>
TO: ABC <[email protected]>
SUBJECT: Simple Message
----------------------------
CONTENT-TYPE: multipart/alternative; boundary=047d7b343d6ad3e4ea04e8ec6579
This is a Multipart
---------------------------

----------------------------
CONTENT-TYPE: text/plain; charset=ISO-8859-1
This is plain text
---------------------------
Hi am a simple message string....

-- 
Regards
xyz

This is the message envelope
---------------------------
FROM: XYZ <[email protected]>
TO: ABC <[email protected]>
SUBJECT: Attachement
----------------------------
CONTENT-TYPE: multipart/mixed; boundary=047d7b343d6a99180904e8ec6751
This is a Multipart
---------------------------

----------------------------
CONTENT-TYPE: text/plain; charset=ISO-8859-1
This is plain text
---------------------------
Hi I've an attachment.Please check

-- 
Regards
XYZ

----------------------------
CONTENT-TYPE: application/octet-stream; name=sample_attachement
This is just an input stream
---------------------------
Submit your Tutorials, White Papers and Articles into our Tutorials Directory. This is a tutorials database where we are keeping all the tutorials shared by the internet community for the benefit of others.


This is the message envelope
---------------------------
FROM: XYZ <[email protected]>
TO: ABC <[email protected]>
SUBJECT: Inline Image
----------------------------
CONTENT-TYPE: multipart/related; boundary=f46d04182582be803504e8ece94b
This is a Multipart
---------------------------

----------------------------
CONTENT-TYPE: text/plain; charset=ISO-8859-1
This is plain text
---------------------------
Hi I've an inline image


[image: Inline image 3]

-- 
Regards
XYZ

----------------------------
CONTENT-TYPE: image/png; name="javamail-mini-logo.png"
content typeimage/png; name="javamail-mini-logo.png"

在这里您可以看到我们的邮箱中有三封邮件。第一封是一封简单的邮件,正文为“Hi am a simple message string....”。第二封邮件有一个附件。如上所示,附件的内容也被打印出来。第三封邮件有一个内嵌图片。

身份验证

我们将修改检查邮件章节中的CheckingMails.java。其内容如下:

package com.tutorialspoint;

import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Store;

public class CheckingMails {

   public static void check(String host, String storeType, String user,
      String password) 
   {
      try {

      // create properties field
      Properties properties = new Properties();

      properties.put("mail.pop3s.host", host);
      properties.put("mail.pop3s.port", "995");
      properties.put("mail.pop3s.starttls.enable", "true");

      // Setup authentication, get session
      Session emailSession = Session.getInstance(properties,
         new javax.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
               return new PasswordAuthentication(
                  "[email protected]", "manisha123");
            }
         });
      // emailSession.setDebug(true);

      // create the POP3 store object and connect with the pop server
      Store store = emailSession.getStore("pop3s");

      store.connect();

      // create the folder object and open it
      Folder emailFolder = store.getFolder("INBOX");
      emailFolder.open(Folder.READ_ONLY);

      // retrieve the messages from the folder in an array and print it
      Message[] messages = emailFolder.getMessages();
      System.out.println("messages.length---" + messages.length);

      for (int i = 0, n = messages.length; i < n; i++) {
         Message message = messages[i];
         System.out.println("---------------------------------");
         System.out.println("Email Number " + (i + 1));
         System.out.println("Subject: " + message.getSubject());
         System.out.println("From: " + message.getFrom()[0]);
         System.out.println("Text: " + message.getContent().toString());
      }

      // close the store and folder objects
      emailFolder.close(false);
      store.close();

      } catch (NoSuchProviderException e) {
         e.printStackTrace();
      } catch (MessagingException e) {
         e.printStackTrace();
      } catch (Exception e) {
         e.printStackTrace();
      }
   }

   public static void main(String[] args) {

      String host = "pop.gmail.com";// change accordingly
      String mailStoreType = "pop3";
      String username = "[email protected]";// change accordingly
      String password = "*****";// change accordingly

      check(host, mailStoreType, username, password);

   }

}
您可以通过取消注释语句emailSession.setDebug(true);来启用调试。

编译和运行

现在我们的类已经准备好了,让我们编译上面的类。我已经将CheckingMails.java类保存到目录:/home/manisha/JavaMailAPIExercise。我们需要将javax.mail.jaractivation.jar这两个jar包添加到类路径中。从命令提示符执行以下命令来编译类(这两个jar包都放在/home/manisha/目录下)

javac -cp /home/manisha/activation.jar:/home/manisha/javax.mail.jar: CheckingMails.java

现在类已编译,执行以下命令运行:

java -cp /home/manisha/activation.jar:/home/manisha/javax.mail.jar: CheckingMails

验证输出

您可以在命令控制台中看到类似以下的消息:

messages.length---3
---------------------------------
Email Number 1
Subject: Today is a nice day
From: XYZ <[email protected]>
Text: javax.mail.internet.MimeMultipart@45f676cb
---------------------------------
Email Number 2
Subject: hiiii....
From: XYZ <[email protected]>
Text: javax.mail.internet.MimeMultipart@37f12d4f
---------------------------------
Email Number 3
Subject: helloo
From: XYZ <[email protected]>
Text: javax.mail.internet.MimeMultipart@3ad5ba3a

回复邮件

本章我们将学习如何使用JavaMail API回复邮件。下面程序中遵循的基本步骤是:

  • 获取包含POP和SMTP服务器详细信息的Session对象。我们需要POP详细信息来检索邮件,需要SMTP详细信息来发送邮件。

  • 创建POP3 store对象并连接到store。

  • 创建Folder对象并打开邮箱中的相应文件夹。

  • 检索邮件。

  • 遍历邮件,如果要回复,则键入“Y”或“y”。

  • 获取邮件的所有信息(收件人、发件人、主题、内容)。

  • 使用Message.reply()方法构建回复邮件。此方法使用正确的收件人和主题配置一个新邮件。该方法采用一个布尔参数,指示是只回复发件人(false)还是回复所有人(true)。

  • 设置邮件的发件人、正文和回复地址,并通过Transport对象的实例发送。

  • 分别关闭Transport、folder和store对象。

这里我们使用了JangoSMTP服务器来发送邮件到我们的目标邮箱地址。设置方法在环境设置章节中解释。

创建 Java 类

创建一个名为ReplyToEmail的java类文件,其内容如下:

package com.tutorialspoint;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.Properties;

import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class ReplyToEmail {
   public static void main(String args[]) 
   {
      Date date = null;

      Properties properties = new Properties();
      properties.put("mail.store.protocol", "pop3");
      properties.put("mail.pop3s.host", "pop.gmail.com");
      properties.put("mail.pop3s.port", "995");
      properties.put("mail.pop3.starttls.enable", "true");
      properties.put("mail.smtp.auth", "true");
      properties.put("mail.smtp.starttls.enable", "true");
      properties.put("mail.smtp.host", "relay.jangosmtp.net");
      properties.put("mail.smtp.port", "25");
      Session session = Session.getDefaultInstance(properties);

      // session.setDebug(true);
      try 
      {
         // Get a Store object and connect to the current host
         Store store = session.getStore("pop3s");
         store.connect("pop.gmail.com", "[email protected]",
            "*****");//change the user and password accordingly

         Folder folder = store.getFolder("inbox");
         if (!folder.exists()) {
            System.out.println("inbox not found");
               System.exit(0);
         }
         folder.open(Folder.READ_ONLY);

         BufferedReader reader = new BufferedReader(new InputStreamReader(
            System.in));

         Message[] messages = folder.getMessages();
         if (messages.length != 0) {

            for (int i = 0, n = messages.length; i < n; i++) {
               Message message = messages[i];
               date = message.getSentDate();
               // Get all the information from the message
               String from = InternetAddress.toString(message.getFrom());
               if (from != null) {
                  System.out.println("From: " + from);
               }
               String replyTo = InternetAddress.toString(message
	         .getReplyTo());
               if (replyTo != null) {
                  System.out.println("Reply-to: " + replyTo);
               }
               String to = InternetAddress.toString(message
	         .getRecipients(Message.RecipientType.TO));
               if (to != null) {
                  System.out.println("To: " + to);
               }

               String subject = message.getSubject();
               if (subject != null) {
                  System.out.println("Subject: " + subject);
               }
               Date sent = message.getSentDate();
               if (sent != null) {
                  System.out.println("Sent: " + sent);
               }

               System.out.print("Do you want to reply [y/n] : ");
               String ans = reader.readLine();
               if ("Y".equals(ans) || "y".equals(ans)) {

                  Message replyMessage = new MimeMessage(session);
                  replyMessage = (MimeMessage) message.reply(false);
                  replyMessage.setFrom(new InternetAddress(to));
                  replyMessage.setText("Thanks");
                  replyMessage.setReplyTo(message.getReplyTo());

                  // Send the message by authenticating the SMTP server
                  // Create a Transport instance and call the sendMessage
                  Transport t = session.getTransport("smtp");
                  try {
	   	     //connect to the SMTP server using transport instance
		     //change the user and password accordingly	
	             t.connect("abc", "****");
	             t.sendMessage(replyMessage,
                        replyMessage.getAllRecipients());
                  } finally {
                     t.close();
                  }
                  System.out.println("message replied successfully ....");

                  // close the store and folder objects
                  folder.close(false);
                  store.close();

               } else if ("n".equals(ans)) {
                  break;
               }
            }//end of for loop

         } else {
            System.out.println("There is no msg....");
         }

      } catch (Exception e) {
         e.printStackTrace();
      }

   }

}
您可以通过取消注释语句session.setDebug(true);来启用调试。

编译和运行

现在我们的类已经准备好了,让我们编译上面的类。我已经将ReplyToEmail.java类保存到目录:/home/manisha/JavaMailAPIExercise。我们需要将javax.mail.jaractivation.jar这两个jar包添加到类路径中。从命令提示符执行以下命令来编译类(这两个jar包都放在/home/manisha/目录下)

javac -cp /home/manisha/activation.jar:/home/manisha/javax.mail.jar: ReplyToEmail.java

类编译完成后,执行以下命令运行:

java -cp /home/manisha/activation.jar:/home/manisha/javax.mail.jar: ReplyToEmail

验证输出

您应该在命令控制台中看到以下消息:

From: ABC <[email protected]>
Reply-to: [email protected]
To: XYZ <[email protected]>
Subject: Hi today is a nice day
Sent: Thu Oct 17 15:58:37 IST 2013
Do you want to reply [y/n] : y
message replied successfully ....

检查邮件发送到的收件箱。在本例中,收到的邮件如下所示:

JavaMail API Reply Email

转发邮件

本章我们将学习如何使用JavaMail API转发邮件。下面程序中遵循的基本步骤是:

  • 获取包含POP和SMTP服务器详细信息的Session对象。我们需要POP详细信息来检索邮件,需要SMTP详细信息来发送邮件。

  • 创建POP3 store对象并连接到store。

  • 创建Folder对象并打开邮箱中的相应文件夹。

  • 检索邮件。

  • 遍历邮件,如果要转发,则键入“Y”或“y”。

  • 获取邮件的所有信息(收件人、发件人、主题、内容)。

  • 通过处理构成邮件的各个部分来构建转发邮件。第一部分是邮件正文,第二部分是要转发的邮件。将两者组合成多部分。然后将多部分添加到正确寻址的邮件中并发送。

  • 分别关闭Transport、folder和store对象。

这里我们使用了JangoSMTP服务器来发送邮件到我们的目标邮箱地址。设置方法在环境设置章节中解释。

创建 Java 类

创建一个名为ForwardEmail的java类文件,其内容如下:

package com.tutorialspoint;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.Properties;

import javax.mail.BodyPart;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

public class ForwardEmail {

   public static void main(String[] args) {
      Properties properties = new Properties();
      properties.put("mail.store.protocol", "pop3");
      properties.put("mail.pop3s.host", "pop.gmail.com");
      properties.put("mail.pop3s.port", "995");
      properties.put("mail.pop3.starttls.enable", "true");
      properties.put("mail.smtp.auth", "true");
      properties.put("mail.smtp.host", "relay.jangosmtp.net");
      properties.put("mail.smtp.port", "25");
      Session session = Session.getDefaultInstance(properties);
      try {
         // session.setDebug(true);
         // Get a Store object and connect to the current host
         Store store = session.getStore("pop3s");
         store.connect("pop.gmail.com", "[email protected]",
            "*****");//change the user and password accordingly

         // Create a Folder object and open the folder
         Folder folder = store.getFolder("inbox");
         folder.open(Folder.READ_ONLY);
         BufferedReader reader = new BufferedReader(new InputStreamReader(
            System.in));
         Message[] messages = folder.getMessages();
         if (messages.length != 0) {

         for (int i = 0, n = messages.length; i < n; i++) {
            Message message = messages[i];
            // Get all the information from the message
            String from = InternetAddress.toString(message.getFrom());
            if (from != null) {
               System.out.println("From: " + from);
            }
            String replyTo = InternetAddress.toString(message
               .getReplyTo());
            if (replyTo != null) {
               System.out.println("Reply-to: " + replyTo);
            }
            String to = InternetAddress.toString(message
               .getRecipients(Message.RecipientType.TO));
            if (to != null) {
               System.out.println("To: " + to);
            }

            String subject = message.getSubject();
            if (subject != null) {
               System.out.println("Subject: " + subject);
            }
            Date sent = message.getSentDate();
            if (sent != null) {
               System.out.println("Sent: " + sent);
            }
            System.out.print("Do you want to reply [y/n] : ");
            String ans = reader.readLine();
            if ("Y".equals(ans) || "y".equals(ans)) {
               Message forward = new MimeMessage(session);
               // Fill in header
               forward.setRecipients(Message.RecipientType.TO,
               InternetAddress.parse(from));
               forward.setSubject("Fwd: " + message.getSubject());
               forward.setFrom(new InternetAddress(to));

               // Create the message part
               MimeBodyPart messageBodyPart = new MimeBodyPart();
               // Create a multipart message
               Multipart multipart = new MimeMultipart();
               // set content
               messageBodyPart.setContent(message, "message/rfc822");
               // Add part to multi part
               multipart.addBodyPart(messageBodyPart);
               // Associate multi-part with message
               forward.setContent(multipart);
               forward.saveChanges();

               // Send the message by authenticating the SMTP server
               // Create a Transport instance and call the sendMessage
               Transport t = session.getTransport("smtp");
               try {
                  //connect to the SMTP server using transport instance
		  //change the user and password accordingly
                  t.connect("abc", "*****");
                  t.sendMessage(forward, forward.getAllRecipients());
               } finally {
                  t.close();
               }

               System.out.println("message forwarded successfully....");

            // close the store and folder objects
            folder.close(false);
            store.close();
            }// end if

         }// end for
   }// end if
   } catch (Exception e) {
      e.printStackTrace();
   }
}

}
您可以通过取消注释语句session.setDebug(true);来启用调试。

编译和运行

现在我们的类已经准备好了,让我们编译上面的类。我已经将ForwardEmail.java类保存到目录:/home/manisha/JavaMailAPIExercise。我们需要将javax.mail.jaractivation.jar这两个jar包添加到类路径中。从命令提示符执行以下命令来编译类(这两个jar包都放在/home/manisha/目录下)

javac -cp /home/manisha/activation.jar:/home/manisha/javax.mail.jar: ForwardEmail.java

类编译完成后,执行以下命令运行:

java -cp /home/manisha/activation.jar:/home/manisha/javax.mail.jar: ForwardEmail

验证输出

您应该在命令控制台中看到以下消息:

From: ABC <[email protected]>
Reply-to: [email protected]
To: XYZ <[email protected]>
Subject: Hi today is a nice day
Sent: Thu Oct 17 15:58:37 IST 2013
Do you want to reply [y/n] : y
message forwarded successfully....

检查邮件发送到的收件箱。在本例中,转发的邮件如下所示:

JavaMail API Forward Email JavaMail API Forward Email

删除邮件

本章我们将学习如何使用JavaMail API删除邮件。删除邮件涉及使用与邮件关联的Flags。不同状态有不同的标志,一些是系统定义的,一些是用户定义的。预定义的标志在内部类Flags.Flag中定义,如下所示:

  • Flags.Flag.ANSWERED

  • Flags.Flag.DELETED

  • Flags.Flag.DRAFT

  • Flags.Flag.FLAGGED

  • Flags.Flag.RECENT

  • Flags.Flag.SEEN

  • Flags.Flag.USER

POP协议只支持删除邮件。

删除程序中遵循的基本步骤是:

  • 获取包含POP和SMTP服务器详细信息的Session对象。我们需要POP详细信息来检索邮件,需要SMTP详细信息来发送邮件。

  • 创建POP3 store对象并连接到store。

  • 创建Folder对象,并以READ_WRITE模式打开邮箱中的相应文件夹。

  • 从收件箱文件夹中检索邮件。

  • 遍历邮件,如果要删除邮件,则键入“Y”或“y”,通过在Message对象上调用setFlag(Flags.Flag.DELETED, true)方法来删除。

  • 标记为DELETED的邮件不会被实际删除,除非我们在Folder对象上调用expunge()方法,或关闭带有expunge设置为true的文件夹。

  • 关闭store对象。

创建 Java 类

创建一个名为ForwardEmail的java类文件,其内容如下:

package com.tutorialspoint;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Properties;

import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Store;

public class DeleteEmail {

   public static void delete(String pop3Host, String storeType, String user,
      String password) 
   {
      try 
      {
         // get the session object
         Properties properties = new Properties();
         properties.put("mail.store.protocol", "pop3");
         properties.put("mail.pop3s.host", pop3Host);
         properties.put("mail.pop3s.port", "995");
         properties.put("mail.pop3.starttls.enable", "true");
         Session emailSession = Session.getDefaultInstance(properties);
         // emailSession.setDebug(true);

         // create the POP3 store object and connect with the pop server
         Store store = emailSession.getStore("pop3s");

         store.connect(pop3Host, user, password);

         // create the folder object and open it
         Folder emailFolder = store.getFolder("INBOX");
         emailFolder.open(Folder.READ_WRITE);

         BufferedReader reader = new BufferedReader(new InputStreamReader(
            System.in));
         // retrieve the messages from the folder in an array and print it
         Message[] messages = emailFolder.getMessages();
         System.out.println("messages.length---" + messages.length);
         for (int i = 0; i < messages.length; i++) {
            Message message = messages[i];
            System.out.println("---------------------------------");
            System.out.println("Email Number " + (i + 1));
            System.out.println("Subject: " + message.getSubject());
            System.out.println("From: " + message.getFrom()[0]);

            String subject = message.getSubject();
            System.out.print("Do you want to delete this message [y/n] ? ");
            String ans = reader.readLine();
            if ("Y".equals(ans) || "y".equals(ans)) {
	       // set the DELETE flag to true
	       message.setFlag(Flags.Flag.DELETED, true);
	       System.out.println("Marked DELETE for message: " + subject);
            } else if ("n".equals(ans)) {
	       break;
            }
         }
         // expunges the folder to remove messages which are marked deleted
         emailFolder.close(true);
         store.close();

      } catch (NoSuchProviderException e) {
         e.printStackTrace();
      } catch (MessagingException e) {
         e.printStackTrace();
      } catch (IOException io) {
         io.printStackTrace();
      }
   }

   public static void main(String[] args) {

      String host = "pop.gmail.com";// change accordingly
      String mailStoreType = "pop3";
      String username = "[email protected]";// change accordingly
      String password = "*****";// change accordingly

      delete(host, mailStoreType, username, password);

   }

}
您可以通过取消注释语句emailSession.setDebug(true);来启用调试。

编译和运行

现在我们的类已经准备好了,让我们编译上面的类。我已经将DeleteEmail.java类保存到目录:/home/manisha/JavaMailAPIExercise。我们需要将javax.mail.jaractivation.jar这两个jar包添加到类路径中。从命令提示符执行以下命令来编译类(这两个jar包都放在/home/manisha/目录下)

javac -cp /home/manisha/activation.jar:/home/manisha/javax.mail.jar: DeleteEmail.java

类编译完成后,执行以下命令运行:

java -cp /home/manisha/activation.jar:/home/manisha/javax.mail.jar: DeleteEmail

验证输出

您应该在命令控制台中看到以下消息:

messages.length---1
---------------------------------
Email Number 1
Subject: Testing
From: ABC <[email protected]>
Do you want to delete this message [y/n] ? y
Marked DELETE for message: Testing

Gmail SMTP服务器

在前面所有章节中,我们使用JangoSMTP服务器发送邮件。本章我们将学习Gmail提供的SMTP服务器。Gmail(以及其他一些服务)免费提供其公共SMTP服务器的使用。

Gmail SMTP服务器详细信息可以在这里找到这里。正如您在详细信息中看到的,我们可以使用TLS或SSL连接通过Gmail SMTP服务器发送邮件。

使用Gmail SMTP服务器发送邮件的过程与发送邮件章节中解释的类似,只是我们将更改主机服务器。作为先决条件,发件人邮箱地址应该是有效的Gmail帐户。让我们尝试一个例子。

创建 Java 类

创建一个名为SendEmailUsingGMailSMTP的Java文件,其内容如下:

package com.tutorialspoint;

import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class SendEmailUsingGMailSMTP {
   public static void main(String[] args) {
      // Recipient's email ID needs to be mentioned.
      String to = "[email protected]";//change accordingly

      // Sender's email ID needs to be mentioned
      String from = "[email protected]";//change accordingly
      final String username = "abc";//change accordingly
      final String password = "*****";//change accordingly

      // Assuming you are sending email through relay.jangosmtp.net
      String host = "smtp.gmail.com";

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

      // Get the Session object.
      Session session = Session.getInstance(props,
      new javax.mail.Authenticator() {
         protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(username, password);
         }
      });

      try {
         // Create a default MimeMessage object.
         Message message = new MimeMessage(session);

         // Set From: header field of the header.
         message.setFrom(new InternetAddress(from));

         // Set To: header field of the header.
         message.setRecipients(Message.RecipientType.TO,
         InternetAddress.parse(to));

         // Set Subject: header field
         message.setSubject("Testing Subject");

         // Now set the actual message
         message.setText("Hello, this is sample for to check send "
            + "email using JavaMailAPI ");

         // Send message
         Transport.send(message);

         System.out.println("Sent message successfully....");

      } catch (MessagingException e) {
            throw new RuntimeException(e);
      }
   }
}

这里主机设置为smtp.gmail.com,端口设置为587。这里我们启用了TLS连接。

编译和运行

现在我们的类已经准备好了,让我们编译上面的类。我已经将SendEmailUsingGMailSMTP.java类保存到目录:/home/manisha/JavaMailAPIExercise。我们需要将javax.mail.jaractivation.jar这两个jar包添加到类路径中。从命令提示符执行以下命令来编译类(这两个jar包都放在/home/manisha/目录下)

javac -cp /home/manisha/activation.jar:/home/manisha/javax.mail.jar: SendEmailUsingGMailSMTP.java

现在类已编译,执行以下命令运行:

java -cp /home/manisha/activation.jar:/home/manisha/javax.mail.jar: SendEmailUsingGMailSMTP

验证输出

您应该在命令控制台中看到以下消息:

Sent message successfully....

文件夹管理

到目前为止,我们之前的章节主要处理的是收件箱 (INBOX) 文件夹。这是大多数邮件所在的默认文件夹。有些系统可能将其称为 INBOX,而其他系统则可能使用其他名称。但是,您可以始终使用名称 INBOX 通过 JavaMail API 访问它。

JavaMail API 将文件夹表示为抽象 Folder 类的实例。

public abstract class Folder extends Object

此类声明了用于向服务器请求命名文件夹、从文件夹中删除邮件、搜索文件夹中特定邮件、列出文件夹中的邮件等的方法。

打开文件夹

我们不能直接创建一个文件夹,因为Folder 类中唯一的构造函数是protected(受保护的)。我们可以从以下地方获取Folder

  • 会话 (Session)

  • 存储 (Store)

  • 或其他文件夹

以上所有类都具有签名类似的 getFolder() 方法。

public abstract Folder getFolder(String name) throws MessagingException

一些有助于获取Folder 对象的方法包括:

方法描述
boolean exists()检查文件夹是否存在。在获取 Folder 对象之前使用此方法。
abstract void open(int mode)获取Folder 时,它是关闭的。使用此方法将其打开。mode 可以是 Folder.READ_ONLY 或 Folder.READ_WRITE。
abstract boolean isOpen()如果文件夹已打开,此方法返回true;如果已关闭,则返回false
abstract void close(boolean expunge)关闭文件夹。如果expunge 参数为true,则文件夹中任何已删除的邮件都将从服务器上的实际文件中删除。否则,它们仅被标记为已删除,但邮件仍然可以恢复。

基本文件夹信息

以下是 Folder 类中一些返回有关文件夹基本信息的方法:

方法描述
abstract String getName()返回文件夹的名称,例如“TutorialsPoint Mail”。
abstract String getFullName()返回从根目录开始的完整层次结构名称,例如“books/Manisha/TutorialsPoint Mail”。
URLName getURLName()返回表示此文件夹的 URLName。
abstract Folder getParent()返回包含此文件夹的文件夹名称,即父文件夹。例如,在之前的“TutorialsPoint Mail”示例中为“Manisha”。
abstract int getType()返回一个整数,指示文件夹是否可以包含邮件和/或其他文件夹。
int getMode()它返回两个命名常量之一:Folder.READ_ONLY 或 Folder.READ_WRITE,或者在模式未知时返回 -1。
Store getStore()返回从中检索此文件夹的 Store 对象。
abstract char getSeparator()返回分隔符字符,该字符将此 Folder 的路径名与直接子文件夹的名称分隔开。

管理文件夹

以下是一些有助于管理文件夹的方法:

方法描述
abstract boolean create(int type)这将在此文件夹的 Store 中创建一个新文件夹。其中type 为:Folder.HOLDS_MESSAGES 或 Folder.HOLDS_FOLDERS。如果文件夹创建成功,则返回true;否则返回false
abstract boolean delete(boolean recurse)仅当文件夹关闭时,此方法才会删除文件夹。否则,它将抛出IllegalStateException 异常。如果recursetrue,则会删除子文件夹。
abstract boolean renameTo(Folder f)这将更改此文件夹的名称。必须关闭文件夹才能重命名。否则,将抛出 IllegalStateException 异常。

管理文件夹中的邮件

以下是帮助管理文件夹中邮件的一些方法:

方法描述
abstract void appendMessages(Message[] messages)顾名思义,数组中的邮件将放置在此文件夹的末尾。
void copyMessages(Message[] messages, Folder destination)这会将邮件从此文件夹复制到作为参数给定的指定文件夹。
abstract Message[] expunge()要从文件夹中删除邮件,请将其 Flags.Flag.DELETED 标志设置为 true。要从文件夹中物理删除已删除的邮件,必须调用此方法。

列出文件夹的内容

有四种方法可以列出文件夹包含的文件夹:

方法描述
Folder[] list()这将返回一个数组,其中列出了此文件夹包含的文件夹。
Folder[] listSubscribed()这将返回一个数组,其中列出了此文件夹包含的所有已订阅的文件夹。
abstract Folder[] list(String pattern)这与list() 方法类似,只是它允许您指定一个模式。模式是一个字符串,用于指定与之匹配的文件夹的名称。
Folder[] listSubscribed(String pattern)这与listSubscribed() 方法类似,只是它允许您指定一个模式。模式是一个字符串,用于指定与之匹配的文件夹的名称。

检查邮件

方法描述
abstract int getMessageCount()此方法可以在打开或关闭的文件夹上调用。但是,对于关闭的文件夹,此方法可能会(也可能不会)返回 -1,以指示邮件的确切数量不容易获得。
abstract boolean hasNewMessages()如果自上次打开文件夹以来已向文件夹中添加了新邮件,则此方法返回true
它通过检查文件夹中已设置 RECENT 标志的邮件来返回新邮件计数。int getNewMessageCount()
这可以在打开或关闭的文件夹上调用。但是,对于关闭的文件夹,它可能会返回 -1,以指示获取真实答案的成本太高。int getUnreadMessageCount()

从文件夹中获取邮件

Folder 类提供了四种方法用于从打开的文件夹中检索邮件:

方法描述
abstract Message getMessage(int messageNumber)这将返回文件夹中的第 n 条邮件。文件夹中的第一条邮件编号为 1。
Message[] getMessages()这将返回一个Message 对象数组,表示此文件夹中的所有邮件。
Message[] getMessages(int start, int end)这将返回文件夹中从 start 开始到 end 结束(包含 start 和 end)的Message 对象数组。
Message[] getMessages(int[] messageNumbers)这将返回一个数组,其中仅包含messageNumbers 数组中按编号特别标识的邮件。
void fetch(Message[] messages, FetchProfile fp)预取给定邮件中 FetchProfile 中指定的项目。FetchProfile 参数指定要预取邮件中的哪些标题。

搜索文件夹

如果服务器支持搜索(许多 IMAP 服务器支持,而大多数 POP 服务器不支持),则可以轻松搜索满足特定条件的邮件文件夹。这些条件编码在 SearchTerm 对象中。以下两种搜索方法:

方法描述
Message[] search(SearchTerm term)搜索此文件夹中与指定搜索条件匹配的邮件。返回包含匹配邮件的数组。如果未找到匹配项,则返回空数组。
Message[] search(SearchTerm term, Message[] messages)搜索给定的邮件数组中与指定搜索条件匹配的邮件。返回包含匹配邮件的数组。如果未找到匹配项,则返回空数组。指定的 Message 对象必须属于此文件夹。

标志

当您需要更改文件夹中整个邮件集的标志时,标志修改非常有用。以下是 Folder 类中提供的方法:

方法描述
void setFlags(Message[] messages, Flags flag, boolean value)设置数组中指定的邮件的指定标志。
void setFlags(int start, int end, Flags flag, boolean value)设置编号从 start 到 end(包含 start 和 end)的邮件的指定标志。
void setFlags(int[] messageNumbers, Flags flag, boolean value)设置邮件编号在数组中的邮件的指定标志。
abstract Flags getPermanentFlags()返回此文件夹支持的所有邮件的标志。

配额管理

在 JavaMail 中,配额是电子邮件存储中邮件数量或金额的限制或固定数量。每个邮件服务请求都计入 JavaMail API 调用配额。电子邮件服务可以应用以下配额标准:

  • 包括附件在内的传出邮件的最大大小。

  • 包括附件在内的传入邮件的最大大小。

  • 管理员为收件人时邮件的最大大小。

对于配额管理,JavaMail 有以下类:

描述
public class Quota此类表示给定配额根目录的一组配额。每个配额根目录都有一组资源,由 Quota.Resource 类表示。每个资源都有一个名称(例如,“STORAGE”)、当前使用情况和使用限制。此类只有一个方法setResourceLimit(String name, long limit)
public static class Quota.Resource表示配额根目录中的单个资源。
public interface QuotaAwareStore支持配额的 Store 实现的接口。getQuotasetQuota 方法支持由 IMAP QUOTA 扩展定义的配额模型。GmailSSLStore、GmailStore、IMAPSSLStore、IMAPStore 是此接口的已知实现类。

让我们在以下部分查看一个示例,该示例检查邮件存储名称、限制及其使用情况。

创建 Java 类

创建一个名为QuotaExample 的 Java 类文件,其内容如下所示(此处省略示例代码)。

package com.tutorialspoint;

import java.util.Properties;

import javax.mail.Quota;
import javax.mail.Session;
import javax.mail.Store;

import com.sun.mail.imap.IMAPStore;

public class QuotaExample 
{
   public static void main(String[] args) 
   {
      try 
      {
         Properties properties = new Properties();
         properties.put("mail.store.protocol", "imaps");
         properties.put("mail.imaps.port", "993");
         properties.put("mail.imaps.starttls.enable", "true");
         Session emailSession = Session.getDefaultInstance(properties);
         // emailSession.setDebug(true);

         // create the IMAP3 store object and connect with the pop server
         Store store = emailSession.getStore("imaps");

         //change the user and password accordingly
         store.connect("imap.gmail.com", "[email protected]", "*****");
         IMAPStore imapStore = (IMAPStore) store;
         System.out.println("imapStore ---" + imapStore);

         //get quota
         Quota[] quotas = imapStore.getQuota("INBOX");
         //Iterate through the Quotas
         for (Quota quota : quotas) {
            System.out.println(String.format("quotaRoot:'%s'",
               quota.quotaRoot));
            //Iterate through the Quota Resource
            for (Quota.Resource resource : quota.resources) {
               System.out.println(String.format(
                  "name:'%s', limit:'%s', usage:'%s'", resource.name,
                  resource.limit, resource.usage));
            }
         }
      } catch (Exception e) 
      {
         e.printStackTrace();
      }
   }
}

这是通过 IMAP (imap.gmail.com) 服务器与 Gmail 服务的连接,因为 IMAPStore 实现 QuotaAwareStore。获取 Store 对象后,获取 Quota 数组并对其进行迭代并打印相关信息。

编译和运行

现在我们的类已准备就绪,让我们编译上面的类。我已经将 QuotaExample.java 类保存到目录:/home/manisha/JavaMailAPIExercise。我们需要将javax.mail.jaractivation.jar添加到类路径中。从命令提示符执行以下命令来编译类(这两个 jar 文件都位于 /home/manisha/ 目录中):

javac -cp /home/manisha/activation.jar:/home/manisha/javax.mail.jar: QuotaExample.java

现在类已编译,执行以下命令运行:

java -cp /home/manisha/activation.jar:/home/manisha/javax.mail.jar: QuotaExample

验证输出

您应该在命令控制台中看到类似的消息。

imapStore ---imaps://abc%[email protected]
quotaRoot:''
name:'STORAGE', limit:'15728640', usage:'513'

退回邮件

邮件可能由于多种原因而被退回。此问题在rfc1211 中进行了深入讨论。只有服务器才能确定特定邮箱或用户名是否存在。当服务器检测到错误时,它将向原始邮件的发件人返回一条邮件,指示失败的原因。

有很多互联网标准涵盖了投递状态通知,但是大量服务器不支持这些新标准,而是使用临时技术来返回此类失败邮件。因此,很难将退回邮件与导致问题的原始邮件相关联。

JavaMail 包含对解析投递状态通知的支持。有很多技术和启发式方法可以解决此问题。其中一项技术是可变信封返回路径。您可以设置信封中的返回路径,如下面的示例所示。这是退回邮件发送到的地址。您可能希望将其设置为与 From: 标头不同的通用地址,以便您可以处理远程退回邮件。这可以通过在 JavaMail 中设置mail.smtp.from 属性来完成。

创建 Java 类

创建一个名为SendEmail 的 Java 类文件,其内容如下:

import java.util.Properties;

import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class SendEmail {
   public static void main(String[] args) throws Exception {
      String smtpServer = "smtp.gmail.com";
      int port = 587;
      final String userid = "youraddress";//change accordingly
      final String password = "*****";//change accordingly
      String contentType = "text/html";
      String subject = "test: bounce an email to a different address " +
				"from the sender";
      String from = "[email protected]";
      String to = "[email protected]";//some invalid address
      String bounceAddr = "[email protected]";//change accordingly
      String body = "Test: get message to bounce to a separate email address";

      Properties props = new Properties();

      props.put("mail.smtp.auth", "true");
      props.put("mail.smtp.starttls.enable", "true");
      props.put("mail.smtp.host", smtpServer);
      props.put("mail.smtp.port", "587");
      props.put("mail.transport.protocol", "smtp");
      props.put("mail.smtp.from", bounceAddr);

      Session mailSession = Session.getInstance(props,
         new javax.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
               return new PasswordAuthentication(userid, password);
            }
         });

      MimeMessage message = new MimeMessage(mailSession);
      message.addFrom(InternetAddress.parse(from));
      message.setRecipients(Message.RecipientType.TO, to);
      message.setSubject(subject);
      message.setContent(body, contentType);

      Transport transport = mailSession.getTransport();
      try {
         System.out.println("Sending ....");
         transport.connect(smtpServer, port, userid, password);
         transport.sendMessage(message,
            message.getRecipients(Message.RecipientType.TO));
         System.out.println("Sending done ...");
      } catch (Exception e) {
         System.err.println("Error Sending: ");
         e.printStackTrace();

      }
      transport.close();
   }// end function main()
}

在这里我们可以看到属性mail.smtp.from 设置的值与from 地址不同。

编译和运行

现在我们的类已准备就绪,让我们编译上面的类。我已经将 SendEmail.java 类保存到目录:/home/manisha/JavaMailAPIExercise。我们需要在类路径中使用 jar 文件javax.mail.jaractivation.jar。执行以下命令从命令提示符编译该类(这两个 jar 文件都放在 /home/manisha/ 目录中):

javac -cp /home/manisha/activation.jar:/home/manisha/javax.mail.jar: SendEmail.java

现在类已编译,执行以下命令运行:

java -cp /home/manisha/activation.jar:/home/manisha/javax.mail.jar: SendEmail

验证输出

您应该在命令控制台中看到以下消息:

Sending ....
Sending done ...

SMTP 服务器

SMTP 是简单邮件传输协议的首字母缩写。它是用于在互联网协议 (IP) 网络上进行电子邮件 (电子邮件) 传输的互联网标准。SMTP 使用 TCP 端口 25。通过 SSL 保护的 SMTP 连接简称为 SMTPS,尽管 SMTPS 本身并不是一种协议。

JavaMail API 包含com.sun.mail.smtp包,该包充当 SMTP 协议提供程序以访问 SMTP 服务器。下表列出了此包中包含的类

描述
SMTPMessage此类是 MimeMessage 类的特化,允许您指定在通过 SMTP 发送此邮件时将使用的各种 SMTP 选项和参数。
SMTPSSLTransport此类使用通过 SSL 的 SMTP 来实现 Transport 抽象类,用于邮件提交和传输。
SMTPTransport此类使用 SMTP 来实现 Transport 抽象类,用于邮件提交和传输。

下表列出了抛出的异常

异常描述
SMTPAddressFailedException当无法发送邮件时抛出此异常。
SMTPAddressSucceededExceptionmail.smtp.reportsuccess属性为 true 时,此异常链接到 SendFailedException。
SMTPSenderFailedException当无法发送邮件时抛出此异常。
SMTPSendFailedException当无法发送邮件时抛出此异常。此异常包含邮件服务器拒绝的发送方地址。

com.sun.mail.smtp提供程序可以选择使用 SMTP 身份验证。要使用 SMTP 身份验证,您需要设置mail.smtp.auth属性,或者在连接到 SMTP 服务器时为 SMTP 传输提供用户名和密码。您可以使用以下方法之一执行此操作

  • 在创建邮件会话时提供 Authenticator 对象,并在 Authenticator 回调期间提供用户名和密码信息。可以设置mail.smtp.user属性来为回调提供默认用户名,但仍然需要显式提供密码。此方法允许您使用静态 Transport send 方法发送邮件。例如

  • Transport.send(message);
    
  • 使用用户名和密码参数显式调用 Transport connect 方法。例如

    Transport tr = session.getTransport("smtp");
    tr.connect(smtphost, username, password);
    msg.saveChanges();
    tr.sendMessage(msg, msg.getAllRecipients());
    tr.close();
    

SMTP 协议提供程序支持以下属性,这些属性可以在 JavaMail Session 对象中设置。这些属性始终设置为字符串。例如

 props.put("mail.smtp.port", "587");

IMAP 服务器

IMAP 是互联网邮件访问协议的首字母缩写。它是一种应用程序层互联网协议,允许电子邮件客户端访问远程邮件服务器上的电子邮件。IMAP 服务器通常监听众所周知的端口 143。IMAP over SSL (IMAPS) 端口号为 993。

IMAP 支持在线和离线两种操作模式。使用 IMAP 的电子邮件客户端通常会将邮件保留在服务器上,直到用户显式删除它们。

com.sun.mail.imap是 JavaMail API 的 IMAP 协议提供程序,它提供对 IMAP 消息存储的访问。下表列出了此提供程序的接口和类

类/接口描述
IMAPFolder.ProtocolCommand这是一个用于用户定义的 IMAP 协议命令的简单接口
ACL这是一个类。特定身份验证标识符(用户或组)的访问控制列表条目。
IMAPFolder此类实现了一个 IMAP 文件夹。
IMAPFolder.FetchProfileItem这是一个用于获取标头的类。
IMAPMessage此类实现了一个 ReadableMime 对象。
IMAPMessage.FetchProfileCondition此类实现要对文件夹中的每条邮件执行的测试。
IMAPSSLStore此类通过 SSL 提供对 IMAP 消息存储的访问。
IMAPStore此类提供对 IMAP 消息存储的访问。
Rights此类表示身份验证标识符(例如,用户或组)的一组权限。
Rights.Right此内部类表示单个权限。
SortTerm根据 RFC 5256 定义的特定排序标准。

关于此提供程序的一些注意事项

  • 此提供程序同时支持 IMAP4 和 IMAP4rev1 协议。

  • 已连接的 IMAPStore 保持一个 IMAP 协议对象的池,用于与 IMAP 服务器通信。当打开文件夹并需要新的 IMAP 协议对象时,IMAPStore 将从连接池中提供它们,或者如果没有可用的对象,则创建它们。当文件夹关闭时,如果池中……,则其 IMAP 协议对象将返回到连接池。

  • 已连接的 IMAPStore 对象可能会也可能不会维护一个单独的 IMAP 协议对象,该对象为存储提供与 IMAP 服务器的专用连接。

POP3 服务器

邮局协议 (POP) 是一种应用程序层互联网标准协议,本地电子邮件客户端使用它通过 TCP/IP 连接从远程服务器检索电子邮件。POP 支持对远程邮箱访问的简单下载和删除要求。POP3 服务器监听众所周知的端口 110。

com.sun.mail.pop3是 JavaMail API 的 POP3 协议提供程序,它提供对 POP3 消息存储的访问。下表列出了此包中的类

名称描述
POP3FolderPOP3 文件夹(只能是“INBOX”)。
POP3MessagePOP3 消息。
POP3SSLStore使用 SSL 的 POP3 消息存储。
POP3StorePOP3 消息存储。

关于此提供程序的一些注意事项

  • POP3 提供程序仅支持名为INBOX的单个文件夹。由于 POP3 协议的限制,许多 JavaMail API 功能(如事件通知、文件夹管理、标志管理等)都不允许。

  • 通过使用协议名称pop3或表单pop3://user:password@host:port/INBOX的 URL,通过 JavaMail API 访问 POP3 提供程序。

  • POP3 不支持永久标志。例如,Flags.Flag.RECENT标志永远不会为 POP3 消息设置。应用程序需要确定 POP3 邮箱中的哪些邮件是新的

  • POP3 不支持 Folder.expunge() 方法。要删除和清除邮件,请在邮件上设置 Flags.Flag.DELETED 标志,然后使用 Folder.close(true) 方法关闭文件夹。

  • POP3 不提供接收日期,因此 getReceivedDate 方法将返回 null。

  • 当访问 POP3 消息的标头时,POP3 提供程序使用 TOP 命令来获取所有标头,然后将它们缓存。

  • 当访问 POP3 消息的内容时,POP3 提供程序使用 RETR 命令来获取整个消息。

  • 可以使用POP3Message.invalidate方法在不关闭文件夹的情况下使缓存的数据失效。

广告