Javamail Api 简明教程

JavaMail API - Quick Guide

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

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

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

  1. SMTPSimple Mail Transfer Protocol 的缩写。它提供了一种传递电子邮件的机制。

  2. POPPost Office Protocol 的缩写。POP 是互联网上大多数人用来获取邮件的机制。它定义了对每个用户单个邮箱的支持。RFC 1939 定义了此协议。

  3. IMAPInternet Message Access Protocol 的缩写。它是一种用于接收邮件的高级协议。它除了对每个用户的多个邮箱提供支持以外,还提供对多个用户共享邮箱的支持。它在 RFC 2060 中定义。

  4. MIMEMultipurpose Internet Mail Extensions 的缩写。它不是邮件传输协议。相反,它定义了所传输内容的内容:邮件的格式、附件等等。这里有多个不同的文件生效:RFC 822、RFC 2045、RFC 2046 和 RFC 2047。作为 JavaMail API 的用户,你通常不必担心这些格式。但是,这些格式确实存在并且你的程序正在使用它们。

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

这些详细信息将在后续章节中涉及。

Architecture

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

architecture

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

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

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

Environment Setup

使用 Java 应用程序发送电子邮件非常简单,但首先应该在计算机上安装 JavaMail APIJava Activation Framework (JAF)

  1. 可以从 Java 的标准网站下载最新版本的 JavaMail (Version 1.5.0)

  2. 可以从 Java 的标准网站下载最新版本的 JAF (Version 1.1.1)

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

SMTP server

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

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

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

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

Core Classes

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

Class

Description

javax.mail.Session

该 API 的关键类。一个多线程对象表示连接工厂。

javax.mail.Message

对电子邮件建模的抽象类。子类提供实际的实现。

javax.mail.Address

对消息中的地址(发件人和收件人地址)进行建模的抽象类。子类提供具体的实现。

javax.mail.Authenticator

用于保护邮件服务器上邮件资源的抽象类。

javax.mail.Transport

一个抽象类,用于对消息传输机制建模,以发送电子邮件。

javax.mail.Store

用于对消息存储及其访问协议建模的抽象类,用于存储和检索消息。一个存储库分为多个文件夹。

javax.mail.Folder

抽象类,代表邮件消息的文件夹。它可以包含子文件夹。

javax.mail.internet.MimeMessage

消息是一个抽象类,因此必须使用子类;在大多数情况下,您将使用 MimeMessage。MimeMessage 是一个电子邮件消息,可以理解 MIME 类型和头。

javax.mail.internet.InternetAddress

该类使用 RFC822 的语法表示互联网电子邮件地址。典型地址语法采用 user@host.domain 或 Personal Name <user@host.domain> 的形式。

Sending Simple Emails

这里有一个发送简单电子邮件的示例。这里我们使用了 JangoSMTP 服务器,通过该服务器将电子邮件发送到我们的目标电子邮件地址。设置在 Environment Setup 章节中有说明。

发送简单电子邮件遵循的步骤:

  1. Get a Session

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

  3. 将实际消息设置为:message.setText("your text goes here");

  4. 使用 Transport 对象发送消息。

Create Java Class

创建一个 java 类文件 SendEmail ,其内容如下:

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 = "destinationemail@gmail.com";

      // Sender's email ID needs to be mentioned
      String from = "fromemail@gmail.com";
      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 类用于对密码进行身份验证。

Compile and Run

既然我们的类已准备就绪,那么让我们编译上面的类。我已将类 SendEmail.java 保存到目录 /home/manisha/JavaMailAPIExercise 。我们将在类路径中需要 javax.mail.jar 和 activation.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

Verify Output

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

Sent message successfully....

当我在使用 JangoSMTP 向我的 Gmail 地址发送电子邮件时,以下邮件将被接收至我的 Gmail 帐户收件箱:

sendemail

Sending Email With Attachment

这是一个发送带有机器附件的电子邮件的示例。本地机器上的文件 file.txt 位于 /home/manisha/. 在此,我们使用 JangoSMTP 服务器通过该服务器将电子邮件发送至我们目标电子邮件地址。安装在 Environment Setup 章节中有说明。

若要发送带有内嵌图像的电子邮件,请遵循以下步骤:

  1. Get a Session

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

  3. 将实际消息设置为如下所示:messageBodyPart.setText("这是邮件正文");

  4. 创建一个 MimeMultipart 对象。将上面带有在其中设置实际消息的 messageBodyPart 添加至此 multipart 对象。

  5. 接下来,通过创建以下 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);

  6. 接下来,将 multipart 设置在邮件中,如下所示:message.setContent(multipart);

  7. 使用 Transport 对象发送消息。

Create Java Class

创建一个 java 类文件 SendAttachmentInEmail ,其内容如下:

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 = "destinationemail@gmail.com";

      // Sender's email ID needs to be mentioned
      String from = "fromemail@gmail.com";

      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 类用于对密码进行身份验证。

Compile and Run

现在我们的类已准备就绪,我们来编译此类。我已将 SendAttachmentInEmail.java 类保存至目录: /home/manisha/JavaMailAPIExercise 。我们需要 classpath 中的 jar javax.mail.jar 和 activation.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

Verify Output

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

Sent message successfully....

当我在使用 JangoSMTP 向我的 Gmail 地址发送电子邮件时,以下邮件将被接收至我的 Gmail 帐户收件箱:

sendattachment

Sending an HTML Email

这是一个从您的机器发送 HTML 电子邮件的示例。在此,我们使用 JangoSMTP 服务器通过该服务器将电子邮件发送至我们目标电子邮件地址。安装在 Environment Setup 章节中有说明。

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

若要发送带有 HTML 内容的电子邮件,请遵循以下步骤:

  1. Get a Session

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

  3. 使用 setContent() 方法设置实际消息,如下所示:message.setContent("<h1>这是嵌入在 HTML 标记中的实际消息</h1>", "text/html");

  4. 使用 Transport 对象发送消息。

Create Java Class

创建一个 java 类文件 SendHTMLEmail ,其内容如下:

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 = "destinationemail@gmail.com";

      // Sender's email ID needs to be mentioned
      String from = "fromemail@gmail.com";
      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 类用于对密码进行身份验证。

Compile and Run

现在我们的类已准备就绪,我们来编译此类。我已将 SendHTMLEmail.java 类保存至目录: /home/manisha/JavaMailAPIExercise 。我们需要 classpath 中的 jar javax.mail.jar 和 activation.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

Verify Output

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

Sent message successfully....

当我在使用 JangoSMTP 向我的 Gmail 地址发送电子邮件时,以下邮件将被接收至我的 Gmail 帐户收件箱:

sendhtmlemail

Sending Email With Inline Images

这是一个从您的机器发送带有内嵌图像的 HTML 电子邮件的示例。在此,我们使用 JangoSMTP 服务器通过该服务器将电子邮件发送至我们目标电子邮件地址。安装在 Environment Setup 章节中有说明。

若要发送带有内嵌图像的电子邮件,请遵循以下步骤:

  1. Get a Session

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

  3. Create a MimeMultipart object.

  4. 在我们的示例中,电子邮件中会带有 HTML 部分和图像。所以首先创建 HTML 内容并将其设置在 multipart 对象中,如下所示:BodyPart messageBodyPart = new MimeBodyPart();String htmlText = "<H1>你好</H1><img src=\"cid:image\">";messageBodyPart.setContent(htmlText, "text/html");multipart.addBodyPart(messageBodyPart);

  5. 接下来,通过创建以下 DataHandler 添加图像:messageBodyPart = new MimeBodyPart();DataSource fds = new FileDataSource( "/home/manisha/javamail-mini-logo.png");

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

  1. 接下来,将 multipart 设置在邮件中,如下所示:message.setContent(multipart);

  2. 使用 Transport 对象发送消息。

Create Java Class

创建 java 类文件 SendInlineImagesInEmail ,其内容如下:

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 = "destinationemail@gmail.com";

      // Sender's email ID needs to be mentioned
      String from = "fromemail@gmail.com";
      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 类用于对密码进行身份验证。

Compile and Run

现在我们的类准备好了,让我们编译上述类。我已将类 SendInlineImagesInEmail.java 保存到目录中: /home/manisha/JavaMailAPIExercise 。我们需要 classpath 中的 jar javax.mail.jar 和 activation.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

Verify Output

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

Sent message successfully....

当我在使用 JangoSMTP 向我的 Gmail 地址发送电子邮件时,以下邮件将被接收至我的 Gmail 帐户收件箱:

sendinlineimage

Checking Emails

在继续本章之前,需要了解两个方面。它们是 CheckFetch

  1. *使用 JavaMail 检查电子邮件是一个过程,我们在其中打开邮箱中的相应文件夹并获取每封邮件。在这里,我们仅检查每封邮件的标题,即发件人、收件人、主题。不读取内容。

  2. *使用 JavaMail 获取电子邮件是一个过程,我们在其中打开邮箱中的相应文件夹并获取每封邮件。在头部中,我们还可以通过识别内容类型来读取内容。

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

  1. Get a Session

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

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

  4. Get your messages.

  5. 关闭 Store 和 Folder 对象。

Create Java Class

创建 java 类文件 CheckingMails ,其内容如下:

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 = "yourmail@gmail.com";// change accordingly
      String password = "*****";// change accordingly

      check(host, mailStoreType, username, password);

   }

}

Compile and Run

现在我们的类就绪了,让我们编译上面的类。我已经将类 CheckingMails.java 存储到了目录: /home/manisha/JavaMailAPIExercise 。我们需要在类路径中使用 jar 文件 javax.mail.jar 和 activation.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

Verify Output

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

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

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

Fetching Emails

在前一章节中,我们学习了如何检查电子邮件。现在,让我们了解如何获取每封电子邮件并读取其内容。让我们编写一个 Java 类 FetchingEmail 该类将读取以下类型的电子邮件:

  1. Simple email

  2. Email with attachment

  3. Email with inline image

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

  1. Get the Session object.

  2. 创建 POP3 存储对象并连接到存储。

  3. 创建 Folder 对象并在邮箱中打开适当的文件夹。

  4. Retrieve messages.

  5. 分别关闭文件夹和存储对象。

Create Java Class

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

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 =
         "abc@gmail.com";// 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());

   }

}

Compile and Run

既然我们的类已准备就绪,那么让我们编译上面的类。我已将类 FetchingEmail.java 保存到目录 /home/manisha/JavaMailAPIExercise 。我们将在类路径中需要 javax.mail.jar 和 activation.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

Verify Output

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

messages.length---3
---------------------------------
This is the message envelope
---------------------------
FROM: XYZ <xyz@gmail.com>
TO: ABC <abc@gmail.com>
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 <xyz@gmail.com>
TO: ABC <abc@gmail.com>
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 <xyz@gmail.com>
TO: ABC <abc@gmail.com>
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"

此处可以看到我们的邮箱中有三封电子邮件。第一封是包含消息“我是简单的消息字符串……”的简单邮件。第二封邮件有附件。如上所见,附件的内容也已打印出来。第三封邮件有内嵌式图像。

Authentication

我们将修改我们从章节 Checking Emails 中的 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(
                  "manishapatil3may@gmail.com", "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 = "abc@gmail.com";// change accordingly
      String password = "*****";// change accordingly

      check(host, mailStoreType, username, password);

   }

}

Compile and Run

现在我们的类就绪了,让我们编译上面的类。我已经将类 CheckingMails.java 存储到了目录: /home/manisha/JavaMailAPIExercise 。我们需要在类路径中使用 jar 文件 javax.mail.jar 和 activation.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

Verify Output

你可以在命令控制台中看到如下类似的信息:

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

Replying Emails

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

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

  2. 创建 POP3 存储对象并连接到存储。

  3. 创建 Folder 对象并在邮箱中打开适当的文件夹。

  4. Retrieve messages.

  5. 遍历邮件并输入“Y”或“y”,以表示是否要回复。

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

  7. 使用 Message.reply() 方法构建回复邮件。此方法使用适当的收件人和主题配置新的邮件。该方法使用一个布尔参数,表示仅回复发件人(false)还是回复所有人(true)。

  8. 在邮件中设置发件人、文本和回复地址并通过 Transport 对象的实例将其发送出去。

  9. 依次关闭 Transport、folder 和 store 对象。

Create Java Class

创建 java 类文件 ReplyToEmail ,其内容如下:

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", "xyz@gmail.com",
            "*****");//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();
      }

   }

}

Compile and Run

现在我们的类已经准备好了,让我们编译上述类。我已经将类 ReplyToEmail.java 保存到目录: /home/manisha/JavaMailAPIExercise 。我们需要类路径中的 jars javax.mail.jar 和 activation.jar。从命令提示符执行以下命令来编译类(两个 jars 都放在 /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

Verify Output

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

From: ABC <abc@gmail.com>
Reply-to: abc@trioteksolutions.com
To: XYZ <xyz@gmail.com>
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 ....

查看邮件已发送到的收件箱。在我们的案例中,接收到的消息如下所示:

replymessage

Forwarding Emails

在本章中,我们将看到如何使用 JavaMail API 转发电子邮件。以下是程序中遵循的基本步骤:

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

  2. 创建 POP3 存储对象并连接到存储。

  3. 创建 Folder 对象并在邮箱中打开适当的文件夹。

  4. Retrieve messages.

  5. 遍历邮件并键入“Y”或“y”,如果您想要转发。

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

  7. 通过使用组成邮件的部件来构建转发邮件。第一部分将是邮件的文本,第二部分将是要转发的邮件。将两者合并成一个多部分。然后,您可以将多部分添加到正确地址的邮件中并发送它。

  8. 依次关闭 Transport、folder 和 store 对象。

Create Java Class

创建 Java 类文件 ForwardEmail ,其内容如下:

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", "xyz@gmail.com",
            "*****");//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();
   }
}

}

Compile and Run

现在我们的类已经准备好了,让我们编译上述类。我已经将类 ForwardEmail.java 保存到目录: /home/manisha/JavaMailAPIExercise 。我们需要类路径中的 jars javax.mail.jar 和 activation.jar。从命令提示符执行以下命令来编译类(两个 jars 都放在 /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

Verify Output

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

From: ABC <abc@gmail.com>
Reply-to: abc@trioteksolutions.com
To: XYZ <xyz@gmail.com>
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....

查看邮件已发送到的收件箱。在我们的案例中,已转发的邮件将如下所示:

fwdmsg header
fwdmsg body

Deleting Emails

在本章中,我们将看到如何使用 JavaMail API 删除电子邮件。删除邮件涉及使用与邮件关联的标记。不同的状态具有不同的标记,一些由系统定义,一些由用户定义。预定义的标记在内部类 Flags.Flag 中定义,并列在下面:

  1. Flags.Flag.ANSWERED

  2. Flags.Flag.DELETED

  3. Flags.Flag.DRAFT

  4. Flags.Flag.FLAGGED

  5. Flags.Flag.RECENT

  6. Flags.Flag.SEEN

  7. Flags.Flag.USER

POP 协议仅支持删除邮件。

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

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

  2. 创建 POP3 存储对象并连接到存储。

  3. 创建 Folder 对象并在您的邮箱中以 READ_WRITE 模式打开相应的文件夹。

  4. 从收件箱文件夹中检索邮件。

  5. 遍历邮件并键入“Y”或“y”,如果您想通过对 Message 对象调用方法 setFlag(Flags.Flag.DELETED, true) 来删除邮件。

  6. 标记为 DELETED 的邮件不会实际删除,直到我们在 Folder 对象上调用 expunge() 方法或关闭 expunge 设置为 true 的文件夹为止。

  7. Close the store object.

Create Java Class

创建 Java 类文件 ForwardEmail ,其内容如下:

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 = "abc@gmail.com";// change accordingly
      String password = "*****";// change accordingly

      delete(host, mailStoreType, username, password);

   }

}

Compile and Run

现在我们的类已经准备好了,让我们编译上述类。我已经将类 DeleteEmail.java 保存到目录: /home/manisha/JavaMailAPIExercise 。我们需要类路径中的 jars javax.mail.jar 和 activation.jar。从命令提示符执行以下命令来编译类(两个 jars 都放在 /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

Verify Output

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

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

Gmail SMTP Server

在所有以前章节中,我们都使用 JangoSMTP 服务器来发送电子邮件。在本章中,我们将了解由 Gmail 提供的 SMTP 服务器。Gmail(以及其他)提供免费使用其公共 SMTP 服务器。

可以在 here 中找到 Gmail SMTP 服务器详细信息。如您在详细信息中所见,我们可以使用 TLS 或 SSL 连接通过 Gmail SMTP 服务器发送电子邮件。

使用 Gmail SMTP 服务器发送电子邮件的过程与第 Sending Emails 章中所述的过程类似,只是我们需要更改主机服务器。作为先决条件,发件人电子邮件地址应为有效的 Gmail 帐户。让我们尝试一个示例。

Create Java Class

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

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 = "xyz@gmail.com";//change accordingly

      // Sender's email ID needs to be mentioned
      String from = "abc@gmail.com";//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 连接。

Compile and Run

现在,我们的类已经准备就绪,我们来编译上述类。我已经将类 SendEmailUsingGMailSMTP.java 保存到目录:@{}。我们需要 classpath 中的 javax.mail.jar 和 activation.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

Verify Output

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

Sent message successfully....

Folder Management

到目前为止,我们在我们之前的章节中主要使用收件箱文件夹。这是大多数邮件所驻留的默认文件夹。某些系统可能会将其称为 INBOX,而另一些系统可能会将其称为其他名称。但是,您可以始终使用名称 INBOX 从 JavaMail API 访问它。

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

public abstract class Folder extends Object

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

Opening a Folder

我们无法直接创建文件夹,因为 Folder 类中的唯一构造函数受到保护。我们可以从以下位置获取文件夹:

  1. a Session

  2. a Store

  3. or another Folder

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

public abstract Folder getFolder(String name) throws MessagingException

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

Method

Description

boolean exists()

检查文件夹是否实际存在。在获取 Folder 对象之前使用此方法。

abstract void open(int mode)

当您获取 Folder 时,它已关闭。使用此方法将其打开。 mode 可以是 Folder.READ_ONLY 或 Folder.READ_WRITE。

abstract boolean isOpen()

如果文件夹已关闭,此方法将返回 false,如果已打开,将返回 true。

abstract void close(boolean expunge)

关闭文件夹。如果 expunge 参数为 true,则文件夹中任何已删除的邮件都会从服务器上的实际文件中删除。否则,它们将被标记为已删除,但邮件仍可以取消删除。

Basic Folder Info

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

Method

Description

abstract String getName()

返回文件夹的名称,如 “教程点邮件”

abstract String getFullName()

从根目录返回完整的层次结构名称,如“书籍/Manisha/教程点邮件”。

URLName getURLName()

返回表示此文件夹的 URLName。

abstract Folder getParent()

返回包含此文件夹(即父文件夹)的文件夹的名称。例如,从先前的“教程点邮件”示例中的“Manisha”。

abstract int getType()

返回一个 int,表示文件夹是否可以包含邮件和/或其他文件夹。

int getMode()

它会返回两个已命名的常量之一 Folder.READ_ONLY 或 Folder.READ_WRITE,或在未知模式的情况下返回 -1。

Store getStore()

从该文件夹被检索出的商店对象。

abstract char getSeparator()

返回将该 Folder 的路径名与直接子文件夹的名称分隔的定界符字符。

Managing Folder

以下是一些用于管理 Folder 的方法:

Method

Description

abstract boolean create(int type)

在该文件夹的 Store 中创建一个新的文件夹。其中类型可能是:Folder.HOLDS_MESSAGES 或 Folder.HOLDS_FOLDERS。如果文件夹已成功创建,则返回 true;否则,返回 false。

abstract boolean delete(boolean recurse)

仅当文件夹已关闭时,才删除该文件夹。否则会抛出 IllegalStateException。如果 recurse 为 true,那么将删除子文件夹。

abstract boolean renameTo(Folder f)

此方法将更改该文件夹的名称。文件夹必须关闭才能重命名。否则将抛出 IllegalStateException。

Managing Messages in Folders

以下是一些用于管理 Folder 中邮件的方法:

Method

Description

abstract void appendMessages(Message[] messages)

顾名思义,该数组中的邮件被放置在该文件夹的末尾。

void copyMessages(Message[] messages, Folder destination)

此方法将邮件从该文件夹复制到作为参数指定的文件夹中。

abstract Message[] expunge()

若要从文件夹中删除邮件,请将其 Flags.Flag.DELETED 标志设置为 true。若要从文件夹中物理删除已删除邮件,你必须调用此方法。

Listing the Contents of a Folder

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

Method

Description

Folder[] list()

此方法返回一个数组,列出该文件夹包含的所有文件夹。

Folder[] listSubscribed()

此方法返回一个数组,列出该文件夹包含的所有已订阅的文件夹。

abstract Folder[] list(String pattern)

此方法与 list() 方法类似,但允许你指定一个模式。该模式是一个字符串,给出匹配的文件夹的名称。

Folder[] listSubscribed(String pattern)

此方法与 listSubscribed() 方法类似,但允许你指定一个模式。该模式是一个字符串,给出匹配的文件夹的名称。

Checking for Mail

Method

Description

abstract int getMessageCount()

此方法可用于打开或关闭文件夹。但是,对于关闭的文件夹,此方法可能会(或可能不会)返回 -1 以指示确切的邮件数不可用。

abstract boolean hasNewMessages()

如果在上次打开后新邮件已添加到文件夹,此方法返回 true。

int getNewMessageCount()

通过检查 RECENT 标志已设置的文件夹中的邮件,返回新的邮件数量。

int getUnreadMessageCount()

这可以针对打开的或未打开的文件夹进行调用。但是,如果是不打开的文件夹,它可能返回-1,表明获取真实答案的成本太高。

Getting Messages from Folders

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

Method

Description

abstract Message getMessage(int messageNumber)

这将返回文件夹中的第 n 封邮件。文件夹中的第一封邮件为序号 1。

Message[] getMessages()

这将返回表示此文件夹中所有邮件的邮件对象数组。

Message[] getMessages(int start, int end)

这将返回文件夹中从 start 开始至 end 结束(包括 start 和 end)的邮件对象数组。

Message[] getMessages(int[] messageNumbers)

这将返回仅包含由 messageNumbers 数组中的编号特别识别出的邮件的数组。

void fetch(Message[] messages, FetchProfile fp)

为给定的邮件预取 FetchProfile 中指定的项。FetchProfile 参数指定预取邮件中应包含哪些标头。

Searching Folders

如果服务器支持搜索(很多 IMAP 服务器支持,但大多数 POP 服务器不支持),则很容易搜索某个文件夹以查找满足某些条件的邮件。条件通过 SearchTerm 对象进行编码。以下是两种搜索方法:

Method

Description

Message[] search(SearchTerm term)

在此文件夹中搜索与特定搜索条件匹配的消息。返回一个包含匹配消息的数组。如果没有找到匹配的消息,则返回一个空数组。

Message[] search(SearchTerm term, Message[] messages)

搜索给定的消息数组,找到与特定搜索条件匹配的消息。返回一个包含匹配消息的数组。如果没有找到匹配的消息,则返回一个空数组。指定的 Message 对象必须属于这个文件夹。

Flags

当您需要更改一个 Folder 中的所有消息的标志时,标志修改将很有用。以下是 Folder 类中提供的方法:

Method

Description

void setFlags(Message[] messages, Flags flag, boolean value)

设置数组中指定的消息上的指定标志。

void setFlags(int start, int end, Flags flag, boolean value)

将从 start 到 end 中标为数字的消息上的指定标志进行设置,并且 start 和 end 都包含在内。<br>

void setFlags(int[] messageNumbers, Flags flag, boolean value)

设置消息编号位于数组中的邮件上的指定标志。

abstract Flags getPermanentFlags()

返回此文件夹支持的所有邮件的标志。

Quota Management

JavaMail 中的配额是指电子邮件存储中一条消息的限制或固定数量或金额。每次邮件服务请求均计入 JavaMail API 调用配额。电子邮件服务可以应用以下配额标准:

  1. 包括附件在内的发件邮件的最大大小。

  2. 包括附件在内的收件邮件的最大大小。

  3. 管理员作为收件人时的最大信息大小

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

Class

Description

public class Quota

该类表示给定配额根的一组配额。每个配额根都有一组资源,由配额。资源类表示。每个资源都有一个名称(例如“STORAGE”),一个当前使用量和一个使用限制。此方法只有一个 setResourceLimit(String name, long limit)。

public static class Quota.Resource

表示配额根中的单个资源。

public interface QuotaAwareStore

由支持配额的存储实现的接口。getQuota 和 setQuota 方法支持 IMAP QUOTA 扩展定义的配额模型。GmailSSLStore、GmailStore、IMAPSSLStore、IMAPStore 是此接口已知的实现类。

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

Create Java Class

创建一个 java 类文件 QuotaExample ,其内容如下:

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", "abc@gmail.com", "*****");
         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 对象,获取配额数组并遍历它,打印相关信息。

Compile and Run

现在我们的类已经准备好了,让我们编译上述类。我已将类 QuotaExample.java 保存到目录 /home/manisha/JavaMailAPIExercise 中。我们需要 classpath 中的 jars javax.mail.jar 和 activation.jar。从命令提示符执行以下命令来编译类(这两个 jars 都放置在 /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

Verify Output

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

imapStore ---imaps://abc%40gmail.com@imap.gmail.com
quotaRoot:''
name:'STORAGE', limit:'15728640', usage:'513'

Bounced Messages

邮件可能会因多种原因而反弹。这个问题在 rfc1211 中进行了深入讨论。只有服务器才能确定特定邮箱或用户名是否存在。当服务器检测到错误时,它会返回一条消息,说明原始邮件发送者失败的原因。

有很多 Internet 标准包含传递状态通知,但是大量服务器不支持这些新标准,而是使用特殊技术来返回此类失败消息。因此,将退信与导致问题的原始邮件关联起来非常困难。

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

Create Java Class

创建一个 java 类文件 SendEmail ,其内容如下:

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 = "youraddress@gmail.com";
      String to = "bouncer@fauxmail.com";//some invalid address
      String bounceAddr = "toaddress@gmail.com";//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 的设置不同于发件人地址。

Compile and Run

既然我们的类已准备就绪,那么让我们编译上面的类。我已将类 SendEmail.java 保存到目录 /home/manisha/JavaMailAPIExercise 。我们将在类路径中需要 javax.mail.jar 和 activation.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

Verify Output

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

Sending ....
Sending done ...

SMTP Servers

SMTP 是 Simple Mail Transfer Protocol 的缩写。它是一种用于通过因特网协议 (IP) 网络传输电子邮件 (e-mail) 的因特网标准。SMTP 使用 TCP 端口 25。由 SSL 保护的 SMTP 连接被称为 SMTPS,尽管 SMTPS 自身并不是一种协议。

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

Class

Description

SMTPMessage

此类是 MimeMessage 类的专业化版本,允许您指定在通过 SMTP 发送此消息时将使用的各种 SMTP 选项和参数。

SMTPSSLTransport

此类使用 SMTP over SSL 针对消息提交和传输实现 Transport 抽象类。

SMTPTransport

此类使用 SMTP 针对消息提交和传输实现 Transport 抽象类。

下表列出了引发的异常:

Exception

Description

SMTPAddressFailedException

当无法发送消息时引发此异常。

SMTPAddressSucceededException

当 mail.smtp.reportsuccess 属性为 true 时,此异常会链接到 SendFailedException。

SMTPSenderFailedException

当无法发送消息时引发此异常。

SMTPSendFailedException

当无法发送消息时引发此异常。该异常包括邮件服务器拒绝的发件人地址。

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

  1. 在创建邮件会话时提供 Authenticator 对象,并在 Authenticator 回调期间提供用户名和密码信息。可以设置 mail.smtp.user 属性以提供回调的默认用户名,但仍需要明确提供密码。通过这种方法,您可以使用静态传输 send 方法来发送消息。例如:

  2. 使用用户名和密码参数明确调用 Transport connect 方法。例如:Transport tr = session.getTransport("smtp");tr.connect(smtphost, username, password);msg.saveChanges();tr.sendMessage(msg, msg.getAllRecipients());tr.close();

SMTP 协议提供者支持以下属性,可以在 JavaMail 会话对象中设置这些属性。这些属性始终以字符串形式设置。例如:

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

IMAP Servers

IMAP 是 Internet Message Access Protocol 的首字母缩写。它是一种应用程序层 Internet 协议,允许电子邮件客户端访问远程邮件服务器上的电子邮件。IMAP 服务器通常侦听知名端口 143。SSL 上的 IMAP(IMAPS)分配到端口号 993。

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

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

Class/Interface

Description

IMAPFolder.ProtocolCommand

这是一个用于用户定义 IMAP 协议命令的简单接口。

ACL

这是一个类。某种认证标识符(用户或组)的访问控制列表条目。

IMAPFolder

这个类实现了 IMAP 文件夹。

IMAPFolder.FetchProfileItem

这个类用于获取标题。

IMAPMessage

这个类实现了 ReadableMime 对象。

IMAPMessage.FetchProfileCondition

这个类实现了对文件夹中的每封邮件执行的测试。

IMAPSSLStore

这个类提供对通过 SSL 的 IMAP 邮件存储的访问权限。

IMAPStore

这个类提供对 IMAP 邮件存储的访问权限。

Rights

这个类表示认证标识符(例如,用户或组)的权利集。

Rights.Right

这个内部类代表了单项权利。

SortTerm

一种特殊排序条件,由 RFC 5256 定义。

在上面此提供程序这部分中需要注意一些要点:

  1. 此提供程序支持 IMAP4 和 IMAP4rev1 协议。

  2. 一个已连接的 IMAPStore 维护了一个 IMAP 协议对象池,用于与 IMAP 服务器进行通信。当打开文件夹并需要新的 IMAP 协议对象时,IMAPStore 将从连接池中提供它们,或者在没有可用时创建它们。当一个文件夹被关闭时,如果连接池 .

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

POP3 Servers

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

com.sun.mail.pop3 是适用于 JavaMail API 的 POP3 协议提供商,可访问 POP3 消息存储。下表列出了此包中的类:

Name

Description

POP3Folder

POP3 文件夹(只能是“收件箱”)。

POP3Message

A POP3 Message.

POP3SSLStore

使用 SSL 的 POP3 消息存储。

POP3Store

A POP3 Message Store.

在上面此提供程序这部分中需要注意一些要点:

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

  2. 可以通过使用协议名称 pop3 或形式为 pop3://user:password@host:port/INBOX 的 URL 来通过 JavaMail API 访问 POP3 提供商。

  3. POP3 不支持永久标记。例如,Flags.Flag.RECENT 标记将永远不会对 POP3 消息设置。由应用程序确定 POP3 邮箱中的哪些消息是新消息。

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

  5. POP3 不提供收件日期,因此 getReceivedDate 方法将返回 null。

  6. 当访问 POP3 邮件的标头时,POP3 提供商使用 TOP 命令获取所有标头,然后将这些标头缓存起来。

  7. 当访问 POP3 消息的内容时,POP3 提供商使用 RETR 命令获取整个消息。

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