使用 IMAP(javamail API)从 gmail 访问电子邮件

Posted

技术标签:

【中文标题】使用 IMAP(javamail API)从 gmail 访问电子邮件【英文标题】:Accessing emails from gmail using IMAP ( javamail API) 【发布时间】:2012-03-05 00:46:51 【问题描述】:

我正在尝试借助 JavaMail API 通过 IMAP 访问来自 Gmail 帐户的电子邮件。我想知道为什么该代码适用于一个电子邮件帐户但不适用于另一个。

我可以访问两个电子邮件帐户的Inbox 文件夹。但是对于其中一个电子邮件帐户,无法访问其他文件夹(如 SPAM([Gmail]/Spam))并引发 FolderNotFoundException 异常。有人可以解释发生了什么问题吗?

提前谢谢你。

代码如下:

import java.io.*;
import java.util.*;
import javax.mail.*;
import javax.mail.Flags.Flag;
import javax.mail.internet.*;

import com.sun.mail.imap.IMAPFolder;
import com.sun.mail.imap.IMAPMessage;


public class FolderFetchIMAP 


    public static void main(String[] args) throws MessagingException, IOException 
        IMAPFolder folder = null;
        Store store = null;
        String subject = null;
        Flag flag = null;
        try 
        
          Properties props = System.getProperties();
          props.setProperty("mail.store.protocol", "imaps");

          Session session = Session.getDefaultInstance(props, null);

          store = session.getStore("imaps");
          store.connect("imap.googlemail.com","myemailid@gmail.com", "password");

          folder = (IMAPFolder) store.getFolder("[Gmail]/Spam"); // This doesn't work for other email account
          //folder = (IMAPFolder) store.getFolder("inbox"); This works for both email account


          if(!folder.isOpen())
          folder.open(Folder.READ_WRITE);
          Message[] messages = folder.getMessages();
          System.out.println("No of Messages : " + folder.getMessageCount());
          System.out.println("No of Unread Messages : " + folder.getUnreadMessageCount());
          System.out.println(messages.length);
          for (int i=0; i < messages.length;i++) 
          

            System.out.println("*****************************************************************************");
            System.out.println("MESSAGE " + (i + 1) + ":");
            Message msg =  messages[i];
            //System.out.println(msg.getMessageNumber());
            //Object String;
            //System.out.println(folder.getUID(msg)

            subject = msg.getSubject();

            System.out.println("Subject: " + subject);
            System.out.println("From: " + msg.getFrom()[0]);
           System.out.println("To: "+msg.getAllRecipients()[0]);
            System.out.println("Date: "+msg.getReceivedDate());
            System.out.println("Size: "+msg.getSize());
            System.out.println(msg.getFlags());
            System.out.println("Body: \n"+ msg.getContent());
            System.out.println(msg.getContentType());

          
        
        finally 
        
          if (folder != null && folder.isOpen())  folder.close(true); 
          if (store != null)  store.close(); 
        

    




【问题讨论】:

【参考方案1】:

它是这样工作的(看起来它不适用于 POP3,但它适用于 IMAP):

     Properties props = new Properties();
     props.put("mail.store.protocol", "imaps");
     Session session = Session.getDefaultInstance(props, null);
     Store store = session.getStore("imaps");
     store.connect("imap.gmail.com", [theMailAccount@gmail.com], [thePasswordOrAppPassword]);

     // You possibly will have to use [Google Mail]/All Mail instead
     Folder inbox = store.getFolder("[Gmail]/All Mail");

【讨论】:

【参考方案2】:

你可以试试下面的代码:

private List<String> getResult1()
  try 
    Properties props = new Properties();
    props.put("mail.store.protocol","imaps");
    Session session = Session.getDefaultInstance(props, null);
    Store store = session.getStore("imaps");
    store.connect("imap.gmail.com", "Email Id", "App Password");

    //if you want mail from specified folder, just change change folder name
    //Folder inbox = store.getFolder("[Gmail]/Drafts");
    Folder inbox = store.getFolder("inbox");

    inbox.open(Folder.READ_ONLY);
    int messageCount = inbox.getMessageCount();
    Log.e("getFolder ", "getResult1: " + store.getDefaultFolder().list("*"));
    javax.mail.Folder[] folders = store.getDefaultFolder().list("*");

    for (javax.mail.Folder folder : folders) 
      if ((folder.getType() & javax.mail.Folder.HOLDS_MESSAGES) != 0)
        Log.e("getFolder ", "getResult1: " + folder.getName() );
      
    

    Log.e("Mail Subject:", "Total Messages:-: " + messageCount );
    javax.mail.Message[] messages = inbox.getMessages();

    System.out.println("------------------------------");
    Log.e("Mail Subject:", "messages: " + messages.toString());
    for (int i = 0; i < messages.length; i++) 
      Log.e("Mail Subject:", "getResult1: " + messages[i].getSubject());
    
    inbox.close(true);
    store.close();
   catch (Exception e) 
    e.printStackTrace();
  
  return null;

【讨论】:

【参考方案3】:
package com.technicalkeeda;

import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;

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

public class GmailInbox 

 public static void main(String[] args) 
  GmailInbox gmail = new GmailInbox();
  gmail.read();
 

 public void read() 
  Properties props = new Properties();
  try 
   props.load(new FileInputStream(new File("C:\\smtp.properties")));
   Session session = Session.getDefaultInstance(props, null);

   Store store = session.getStore("imaps");
   store.connect("smtp.gmail.com", "*************@gmail.com","your_password");

   Folder inbox = store.getFolder("inbox");
   inbox.open(Folder.READ_ONLY);
   int messageCount = inbox.getMessageCount();

   System.out.println("Total Messages:- " + messageCount);

   Message[] messages = inbox.getMessages();
   System.out.println("------------------------------");
   for (int i = 0; i < 10; i++) 
      System.out.println("Mail Subject:- " + messages[i].getSubject());      
   
   inbox.close(true);
   store.close();

   catch (Exception e) 
   e.printStackTrace();
  
 


【讨论】:

在 smtp.properties 中放什么? 您不需要stmp.properties 文件。不管怎样,resources 文件夹是存储*.properties 文件的好地方。【参考方案4】:

其中一个帐户是否有任何机会使用非英语用户界面?

Gmail 文件夹名称已根据用户本地化设置进行本地化。

目前获取本地化文件夹名称的唯一方法是使用 XLIST 命令。

【讨论】:

@Pawel Lesnikowski 您能否详细说明什么是 XLIST 命令以及如何使用它来获取本地化文件夹名称?谢谢.. XLIST 是 Google 添加到 IMAP 协议的扩展之一。它与 LIST 命令非常相似。它的响应包括额外的标志,允许客户端识别文件夹的预期用途。您可以在此处找到示例响应:limilabs.com/blog/localized-gmail-imap-folders我不是 Java 开发人员,因此无法向您展示如何使用 java.mail 发出此命令 @Pawel Lesnikowski 再次感谢..您提供的链接非常有用..我得到了正确的文件夹名称,它们工作正常... 有关信息,code.google.com/p/java-gmail-imap 是针对 Gmail 的 JavaMail 的扩展版本,包括 XLIST 支持。 XLIST 实际上现在已被弃用,谷歌建议您改用 LIST 命令...【参考方案5】:

我不确定这是否有帮助,但我已经看到 gmail 帐户具有不同邮箱的情况,即..

Gmail 帐户 1:-

[[Google Mail]]
[[Google Mail]/All Mail]
[[Google Mail]/Bin]
[[Google Mail]/Drafts]
[[Google Mail]/Important]
[[Google Mail]/Sent Mail]
[[Google Mail]/Spam]
[[Google Mail]/Starred]

Gmail 帐户 2:-

[[Gmail]]
[[Gmail]/All Mail]
[[Gmail]/Bin]
[[Gmail]/Drafts]
[[Gmail]/Important]
[[Gmail]/Sent Mail]
[[Gmail]/Spam]
[[Gmail]/Starred]

【讨论】:

是的,它发生了,这是有用的文档

以上是关于使用 IMAP(javamail API)从 gmail 访问电子邮件的主要内容,如果未能解决你的问题,请参考以下文章

JavaMail 使用 IMAP 读取最近的未读邮件

Java 中的 IMAP 客户端:JavaMail API 还是 Apache Commons Net?

SSL上的JavaMail IMAP非常慢 - 批量获取多条消息

IMAP:(JavaMail)UIDVALIDTY 值总是更改某些文件夹

可以使用 JavaMail 和 Apache Camel Mail (IMAP) 通过服务帐户连接 Microsoft Exchange 共享邮箱吗?

java mail smtp port