使用 IMAP 服务器的邮件
列出服务器上的 MIME 消息 ID
ImapMessageInfo 提供 MIME MessageId 用于在不提取完整邮件的情况下识别邮件。以下代码片段展示了如何列出 MIME messageId。
// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-Java
ImapClient client = new ImapClient();
client.setHost("domain.com");
client.setUsername("username");
client.setPassword("password");
try {
ImapMessageInfoCollection messageInfoCol = client.listMessages("Inbox");
for (ImapMessageInfo info : messageInfoCol) {
// Display MIME Message ID
System.out.println("Message Id = " + info.getMessageId());
}
} catch (java.lang.RuntimeException ex) {
System.out.println(ex.getMessage());
}
列出服务器上的邮件
Aspose.Email 提供了一个含 2 个成员的重载变体 listMessages() 根据查询检索指定数量的邮件。以下代码片段展示了如何列出邮件。
// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-Java
// Create an imapclient with host, user and password
ImapClient client = new ImapClient("localhost", "user", "password");
// Select the inbox folder and Get the message info collection
ImapQueryBuilder builder = new ImapQueryBuilder();
MailQuery query = builder
.or(builder.or(builder.or(builder.or(builder.getSubject().contains(" (1) "), builder.getSubject().contains(" (2) ")), builder.getSubject().contains(" (3) ")),
builder.getSubject().contains(" (4) ")), builder.getSubject().contains(" (5) "));
ImapMessageInfoCollection messageInfoCol4 = client.listMessages(query, 4);
System.out.println((messageInfoCol4.size() == 4) ? "Success" : "Failure");
递归列出服务器上的邮件
IMAP 协议支持递归列出邮箱文件夹中的邮件。这也有助于列出文件夹的子文件夹中的邮件。以下代码片段展示了如何递归列出邮件。
// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-Java
// Create an imapclient with host, user and password
ImapClient client = new ImapClient();
client.setHost("domain.com");
client.setUsername("username");
client.setPassword("password");
client.selectFolder("InBox");
ImapMessageInfoCollection msgsColl = client.listMessages(true);
System.out.println("Total Messages: " + msgsColl.size());
使用多连接列出消息
ImapClient 提供了一个 UseMultiConnection 属性可用于在繁重操作时创建多个连接。您也可以通过使用 ImapClient.ConnectionsQuantity。以下代码片段演示了使用多连接模式列出邮件,并将其性能与单连接模式进行比较。
// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-Java
ImapClient imapClient = new ImapClient();
imapClient.setHost("<HOST>");
imapClient.setPort(993);
imapClient.setUsername("<USERNAME>");
imapClient.setPassword("<PASSWORD>");
imapClient.setSupportedEncryption(EncryptionProtocols.Tls);
imapClient.setSecurityOptions(SecurityOptions.SSLImplicit);
imapClient.selectFolder("Inbox");
imapClient.setConnectionsQuantity(5);
imapClient.setUseMultiConnection(MultiConnectionMode.Enable);
long multiConnectionModeStartTime = System.currentTimeMillis();
ImapMessageInfoCollection messageInfoCol1 = imapClient.listMessages(true);
long multiConnectionModeTimeSpan = System.currentTimeMillis() - multiConnectionModeStartTime;
imapClient.setUseMultiConnection(MultiConnectionMode.Disable);
long singleConnectionModeStartTime = System.currentTimeMillis();
ImapMessageInfoCollection messageInfoCol2 = imapClient.listMessages(true);
long singleConnectionModeTimeSpan = System.currentTimeMillis() - singleConnectionModeStartTime;
double performanceRelation = singleConnectionModeTimeSpan / multiConnectionModeTimeSpan;
System.out.println("Performance Relation: " + performanceRelation);
按降序获取消息
Aspose.Email 提供 ImapClient.listMessagesByPage 方法,列出支持分页的消息。该方法的某些重载 ImapClient.listMessagesByPage 接受 PageSettings 作为参数。 PageSettings 提供一个 AscendingSorting 属性,将其设置为 false 时,返回按降序排列的电子邮件。
以下示例代码演示了 AscendingSorting 属性的 PageSettings 类用于更改电子邮件的顺序。
// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-Java
ImapClient imapClient = new ImapClient();
imapClient.setHost("<HOST>");
imapClient.setPort(993);
imapClient.setUsername("<USERNAME>");
imapClient.setPassword("<PASSWORD>");
imapClient.setSupportedEncryption(EncryptionProtocols.Tls);
imapClient.setSecurityOptions(SecurityOptions.SSLImplicit);
PageSettings pageSettings = new PageSettings();
pageSettings.setAscendingSorting(false);
ImapPageInfo pageInfo = imapClient.listMessagesByPage(5, pageSettings);
ImapMessageInfoCollection messages = pageInfo.getItems();
for (ImapMessageInfo message : messages) {
System.out.println(message.getSubject() + " -> " + message.getDate().toString());
}
从服务器获取消息并保存到磁盘
该 ImapClient 类可以从 IMAP 服务器获取消息,并将消息以 EML 格式保存到本地磁盘。以下步骤用于将消息保存到磁盘:
- 创建该类的实例 ImapClient 类。
- 在 ImapClient 中指定主机名、端口、用户名和密码 构造函数.
- 使用以下方式选择文件夹 selectFolder() 方法。
- 调用 listMessages 方法以获取 ImapMessageInfoCollection 对象。
- 遍历 ImapMessageInfoCollection 集合,调用 saveMessage() 方法,并提供输出路径和文件名。
以下代码片段展示了如何从服务器获取电子邮件并保存。
// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-Java
// Select the inbox folder and Get the message info collection
client.selectFolder(ImapFolderInfo.IN_BOX);
ImapMessageInfoCollection list = client.listMessages();
// Download each message
for (int i = 0; i < list.size(); i++) {
// Save the EML file locally
client.saveMessage(list.get_Item(i).getUniqueId(), dataDir + list.get_Item(i).getUniqueId() + ".eml");
}
以 MSG 格式保存消息
在上述示例中,邮件保存为 EML 格式。要将邮件保存为 MSG 格式,请使用 ImapClient.fetchMessage() 需要调用该方法。它返回一个实例化的 MailMessage 类。该 MailMessage.save() 随后可以调用该方法将消息保存为 MSG。以下代码片段展示了如何将消息保存为 MSG 格式。
// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-Java
// The path to the file directory.
String dataDir = "data/";
// Create an imapclient with host, user and password
ImapClient client = new ImapClient("localhost", "user", "password");
// Select the inbox folder and Get the message info collection
client.selectFolder(ImapFolderInfo.IN_BOX);
ImapMessageInfoCollection list = client.listMessages();
// Download each message
for (int i = 0; i < list.size(); i++) {
// Save the message in MSG format
MailMessage message = client.fetchMessage(list.get_Item(i).getUniqueId());
message.save(dataDir + list.get_Item(i).getUniqueId() + "_out.msg", SaveOptions.getDefaultMsgUnicode());
}
批量获取邮件
ImapClient 提供了一个 fetchMessages 接受序列号或唯一标识的可迭代对象并返回列表的方法 MailMessage。下面的代码片段演示了 fetchMessages 根据序列号和唯一标识获取邮件的方法。
// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-Java
ImapClient imapClient = new ImapClient();
imapClient.setHost("<HOST>");
imapClient.setPort(993);
imapClient.setUsername("<USERNAME>");
imapClient.setPassword("<PASSWORD>");
imapClient.setSupportedEncryption(EncryptionProtocols.Tls);
imapClient.setSecurityOptions(SecurityOptions.SSLImplicit);
ImapMessageInfoCollection messageInfoCol = imapClient.listMessages();
System.out.println("ListMessages Count: " + messageInfoCol.size());
List<Integer> sequenceNumberAr = new ArrayList<Integer>();
List<String> uniqueIdAr = new ArrayList<String>();
for (ImapMessageInfo mi : messageInfoCol) {
sequenceNumberAr.add(mi.getSequenceNumber());
uniqueIdAr.add(mi.getUniqueId());
}
for (MailMessage m : imapClient.fetchMessagesBySequences(sequenceNumberAr)) {
System.out.println("FetchMessages-sequenceNumberAr : " + m.getSubject());
}
for (MailMessage m : imapClient.fetchMessagesByUids(uniqueIdAr)) {
System.out.println("FetchMessages-uniqueIdAr : " + m.getSubject());
}
邮件线程/将邮件组织为对话
Aspose.Email 可以将与同一对话相关的所有转发、回复和全部回复邮件以层次结构方式分组。基本上,IMAP 协议可能支持 RFC-5256 中定义的 THREAD 功能。此外,Gmail 还提供了另一种 IMAP 扩展,称为 X-GM-EXT-1。
以下邮件线程功能可供使用:
- getMessageThreads 方法 - 通过以下方式接收邮件线程 ImapClient.
- boolean getGmExt1Supported - 获取是否支持 Gmail X-GM-EXT-1 扩展的信息。
- boolean getThreadSupported - 获取是否支持 THREAD 扩展的信息。
- String[] getThreadAlgorithms - 获取支持的 THREAD 算法。
以下代码示例展示了如何使用这些功能从 Gmail 获取邮件线程:
ImapClient client = new ImapClient("imap.gmail.com", 993, "username", "password", SecurityOptions.SSLImplicit);
try {
client.selectFolder(ImapFolderInfo.IN_BOX);
// get a list of messages that we'll group by conversation
ImapMessageInfoCollection messages = client.listMessages();
// make sure the IMAP server supports X-GM-EXT-1 extension
if (client.getGmExt1Supported()) {
// gets unique conversationId for our example
Set<String> conversationIds = new HashSet<String>();
for (ImapMessageInfo messageInfo : messages) {
if (messageInfo.getConversationId() != null)
conversationIds.add(messageInfo.getConversationId());
}
for (String conversationId : conversationIds) {
// create the necessary search conditions for a thread
XGMThreadSearchConditions conditions = new XGMThreadSearchConditions();
conditions.setConversationId(conversationId);
conditions.setUseUId(true);
// get results
List<MessageThreadResult> conversation = client.getMessageThreads(conditions);
// print the email conversation in hierarchically manner
printConversaton("", conversation, messages);
System.out.println("--------------------");
}
}
} finally {
client.dispose();
}
/**
* <p>
* Prints the email conversation in hierarchically manner
* </p>
*/
public static void printConversaton(String indent, Iterable<MessageThreadResult> conversation,
Iterable<ImapMessageInfo> messages) {
for (MessageThreadResult thread : conversation) {
for (ImapMessageInfo messageInfo : messages) {
if (thread.getUniqueId().equals(messageInfo.getUniqueId())) {
System.out.println(indent + " (" + thread.getUniqueId() + ") " + messageInfo.getSubject());
break;
}
}
if (thread.getChildMessages().size() != 0) {
printConversaton(indent += "-", thread.getChildMessages(), messages);
}
}
}
如果 IMAP 服务器支持 THREAD 功能,代码会略有变化:
检查 IMAP 服务器是否支持 THREAD 扩展:
if (client.getThreadSupported())
为邮件线程创建合适的搜索条件:
ThreadSearchConditions conditions = new ThreadSearchConditions();
conditions.setAlgorithm(client.getThreadAlgorithms()[0]);
conditions.setUseUId(true);
分页列出消息
在邮箱中包含大量消息的电子邮件服务器场景下,通常希望使用分页支持列出或检索消息。Aspose.Email API ImapClient 让您能够使用分页支持从服务器检索消息。
// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-Java
// This example shows the paging support of ImapClient for listing messages from the server
// Available in Aspose.Email for Java and onwards
final ImapClient client = new ImapClient("host.domain.com", 993, "username", "password");
try {
try {
int messagesNum = 12;
int itemsPerPage = 5;
MailMessage message = null;
// Create some test messages and append these to server's inbox
for (int i = 0; i < messagesNum; i++) {
message = new MailMessage("from@domain.com", "to@domain.com", "EMAILNET-35157 - " + UUID.randomUUID(),
"EMAILNET-35157 Move paging parameters to separate class");
client.appendMessage(ImapFolderInfo.IN_BOX, message);
}
// List messages from inbox
client.selectFolder(ImapFolderInfo.IN_BOX);
ImapMessageInfoCollection totalMessageInfoCol = client.listMessages();
// Verify the number of messages added
System.out.println(totalMessageInfoCol.size());
////////////////// RETREIVE THE MESSAGES USING PAGING SUPPORT////////////////////////////////////
List<ImapPageInfo> pages = new ArrayList<ImapPageInfo>();
PageSettings pageSettings = new PageSettings();
ImapPageInfo pageInfo = client.listMessagesByPage(itemsPerPage, 0, pageSettings);
System.out.println(pageInfo.getTotalCount());
pages.add(pageInfo);
while (!pageInfo.getLastPage()) {
pageInfo = client.listMessagesByPage(itemsPerPage, pageInfo.getNextPage().getPageOffset(), pageSettings);
pages.add(pageInfo);
}
int retrievedItems = 0;
// foreach to while statements conversion
for (ImapPageInfo folderCol : pages) {
retrievedItems += folderCol.getItems().size();
}
System.out.println(retrievedItems);
} finally {
}
} finally {
if (client != null)
client.dispose();
}
递归获取文件夹并读取消息
在本文中,大多数 ImapClient 这些功能用于创建一个应用程序,递归列出来自 IMAP 服务器的所有文件夹及子文件夹。它还将每个文件夹和子文件夹中的消息以 MSG 格式保存到本地磁盘。磁盘上的文件夹和消息以与 IMAP 服务器相同的层次结构创建和保存。以下代码片段展示了如何递归获取消息和子文件夹信息。
// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-Java
public static void run() throws Exception {
// Create an instance of the ImapClient class
ImapClient client = new ImapClient();
// Specify host, username, password, Port and SecurityOptions for your client
client.setHost("imap.gmail.com");
client.setUsername("your.username@gmail.com");
client.setPassword("your.password");
client.setPort(993);
client.setSecurityOptions(SecurityOptions.Auto);
try {
// The root folder (which will be created on disk) consists of host and username
String rootFolder = client.getHost() + "-" + client.getUsername();
// Create the root folder and List all the folders from IMAP server
new File(rootFolder).mkdirs();
ImapFolderInfoCollection folderInfoCollection = client.listFolders();
for (ImapFolderInfo folderInfo : folderInfoCollection) {
// Call the recursive method to read messages and get sub-folders
listMessagesInFolder(folderInfo, rootFolder, client);
}
// Disconnect to the remote IMAP server
client.dispose();
} catch (java.lang.RuntimeException ex) {
System.out.println(ex);
}
System.out.println("Downloaded messages recursively from IMAP server.");
}
/// Recursive method to get messages from folders and sub-folders
private static void listMessagesInFolder(ImapFolderInfo folderInfo, String rootFolder, ImapClient client) {
// Create the folder in disk (same name as on IMAP server)
String currentFolder = "data/";
new File(currentFolder).mkdirs();
// Read the messages from the current folder, if it is selectable
if (folderInfo.getSelectable()) {
// Send status command to get folder info
ImapFolderInfo folderInfoStatus = client.getFolderInfo(folderInfo.getName());
System.out.println(folderInfoStatus.getName() + " folder selected. New messages: " + folderInfoStatus.getNewMessageCount() + ", Total messages: "
+ folderInfoStatus.getTotalMessageCount());
// Select the current folder and List messages
client.selectFolder(folderInfo.getName());
ImapMessageInfoCollection msgInfoColl = client.listMessages();
System.out.println("Listing messages....");
for (ImapMessageInfo msgInfo : msgInfoColl) {
// Get subject and other properties of the message
System.out.println("Subject: " + msgInfo.getSubject());
System.out.println("Read: " + msgInfo.isRead() + ", Recent: " + msgInfo.getRecent() + ", Answered: " + msgInfo.getAnswered());
// Get rid of characters like ? and :, which should not be included in a file name and Save the message in MSG format
String fileName = msgInfo.getSubject().replace(":", " ").replace("?", " ");
MailMessage msg = client.fetchMessage(msgInfo.getSequenceNumber());
msg.save(currentFolder + "\\" + fileName + "-" + msgInfo.getSequenceNumber() + ".msg", SaveOptions.getDefaultMsgUnicode());
}
System.out.println("============================\n");
} else {
System.out.println(folderInfo.getName() + " is not selectable.");
}
try {
// If this folder has sub-folders, call this method recursively to get messages
ImapFolderInfoCollection folderInfoCollection = client.listFolders(folderInfo.getName());
for (ImapFolderInfo subfolderInfo : folderInfoCollection) {
listMessagesInFolder(subfolderInfo, rootFolder, client);
}
} catch (java.lang.RuntimeException e) {
}
}
获取消息 UID 或序列号
Aspose.Email 公共 API 提供以下功能,以获取消息标识信息(如 UID 或序列号),这些信息在处理从服务器接收的消息时可能需要:
MailboxInfo 类 - 表示邮箱中邮件的标识信息。
- getSequenceNumber() 方法 - 获取消息的序列号。
- getUniqueId() 方法 - 获取消息的唯一 ID。
MailMessage 类 - 表示电子邮件消息,并允许访问消息属性,例如主题、正文、发件人和收件人地址等。
- getItemId 方法 - 表示邮箱中消息的标识信息。
以下代码示例演示了如何使用该类从 IMAP 服务器的 "INBOX" 文件夹获取并显示消息详情 ImapClient 类:
try (ImapClient client = new ImapClient(imapHost, port, emailAddress, password, securityOption)) {
ImapMessageInfoCollection msgs = client.listMessages("INBOX");
List<Integer> seqIds = new ArrayList<>();
for (ImapMessageInfo msg : msgs) {
seqIds.add(msg.getSequenceNumber());
}
Iterable<MailMessage> msgsViaFetch = client.fetchMessagesBySequences(seqIds);
for (MailMessage thisMsg : msgsViaFetch) {
System.out.println("Message ID: " + thisMsg.getItemId().getUniqueId()
+ " SequenceNumber: " + thisMsg.getItemId().getSequenceNumber()
+ " Subject: " + thisMsg.getSubject());
}
}
检索额外参数作为摘要信息
// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-Java
final ImapClient client = new ImapClient("host.domain.com", "username", "password");
try {
MailMessage message = new MailMessage("from@domain.com", "to@doman.com", "EMAILNET-38466 - " + UUID.randomUUID().toString(),
"EMAILNET-38466 Add extra parameters for UID FETCH command");
// append the message to the server
String uid = client.appendMessage(message);
// wait for the message to be appended
Thread.sleep(5000);
// Define properties to be fetched from server along with the message
List<String> messageExtraFields = Arrays.asList("X-GM-MSGID", "X-GM-THRID");
// retreive the message summary information using it's UID
ImapMessageInfo messageInfoUID = client.listMessage(uid, messageExtraFields);
// retreive the message summary information using it's sequence number
ImapMessageInfo messageInfoSeqNum = client.listMessage(1, messageExtraFields);
// List messages in general from the server based on the defined properties
ImapMessageInfoCollection messageInfoCol = client.listMessages(messageExtraFields);
ImapMessageInfo messageInfoFromList = messageInfoCol.get_Item(0);
// verify that the parameters are fetched in the summary information
for (String paramName : messageExtraFields) {
System.out.println(messageInfoFromList.getExtraParameters().containsKey(paramName));
System.out.println(messageInfoUID.getExtraParameters().containsKey(paramName));
System.out.println(messageInfoSeqNum.getExtraParameters().containsKey(paramName));
}
} finally {
if (client != null)
client.dispose();
}
获取 List-Unsubscribe 标头信息
List-Unsubscribe 标头包含用于取消订阅电子邮件列表(例如广告、新闻稿等)的 URL。要获取 List-Unsubscribe 标头,请使用 listUnsubscribe 属性的 ImapMessageInfo 类。以下示例展示了该类的使用 listUnsubscribe 获取 List-Unsubscribe 标头的属性。
// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-Java
ImapClient imapClient = new ImapClient();
imapClient.setHost("<HOST>");
imapClient.setPort(993);
imapClient.setUsername("<USERNAME>");
imapClient.setPassword("<PASSWORD>");
imapClient.setSupportedEncryption(EncryptionProtocols.Tls);
imapClient.setSecurityOptions(SecurityOptions.SSLImplicit);
ImapMessageInfoCollection messageInfoCol = imapClient.listMessages();
for (ImapMessageInfo imapMessageInfo : messageInfoCol) {
System.out.println("ListUnsubscribe Header: " + imapMessageInfo.getListUnsubscribe());
}