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

22

我需要从Gmail中获取未读邮件。我正在使用Java Mail API。默认情况下,该API按从最旧到最新的顺序检索邮件。但是我需要先检索最近的邮件。这是否可能?谢谢。

4个回答

43

这是一个例子。不要忘记在你的类路径中添加javax.mail

import javax.mail.*;
import javax.mail.search.FlagTerm;
import java.util.*;

public class GmailFetch {

  public static void main( String[] args ) throws Exception {

    Session session = Session.getDefaultInstance(new Properties( ));
    Store store = session.getStore("imaps");
    store.connect("imap.googlemail.com", 993, "username@gmail.com", "password");
    Folder inbox = store.getFolder( "INBOX" );
    inbox.open( Folder.READ_ONLY );

    // Fetch unseen messages from inbox folder
    Message[] messages = inbox.search(
        new FlagTerm(new Flags(Flags.Flag.SEEN), false));

    // Sort messages from recent to oldest
    Arrays.sort( messages, ( m1, m2 ) -> {
      try {
        return m2.getSentDate().compareTo( m1.getSentDate() );
      } catch ( MessagingException e ) {
        throw new RuntimeException( e );
      }
    } );

    for ( Message message : messages ) {
      System.out.println( 
          "sendDate: " + message.getSentDate()
          + " subject:" + message.getSubject() );
    }
  }
}

8

请确保使用IMAP协议,因为它支持标记功能。

对您的代码进行以下更改:

  1. replace inbox.open( Folder.READ_ONLY ); by inbox.open( Folder.READ_WRITE );
  2. Then after reading the message, set the flag like so:

    message.setFlag(Flags.Flag.SEEN, true);
    

完整示例:

    import javax.mail.*;
    import javax.mail.search.FlagTerm;
    import java.util.*;

    public class GmailFetch {

      public static void main( String[] args ) throws Exception {

        Session session = Session.getDefaultInstance(new Properties( ));
        Store store = session.getStore("imaps");
        store.connect("imap.googlemail.com", 993, "username@gmail.com", "password");
        Folder inbox = store.getFolder( "INBOX" );
        inbox.open( Folder.READ_WRITE );

        // Fetch unseen messages from inbox folder
        Message[] messages = inbox.search(
            new FlagTerm(new Flags(Flags.Flag.SEEN), false));

        // Sort messages from recent to oldest
        Arrays.sort( messages, ( m1, m2 ) -> {
          try {
            return m2.getSentDate().compareTo( m1.getSentDate() );
          } catch ( MessagingException e ) {
            throw new RuntimeException( e );
          }
        } );

        for ( Message message : messages ) {
          System.out.println( 
              "sendDate: " + message.getSentDate()
              + " subject:" + message.getSubject() );
              message.setFlag(Flags.Flag.SEEN, true);
        }
      }
    }

为什么需要这个?已经有一个被接受的答案,而且已经三年了... - Nico Haase
1
我同意你的看法,@NicoHaase。我认为这位发帖者想要表达的是,你应该将SEEN标志设置为true,以便将其标记为已读,这样下次运行程序时就不会再请求该消息了。 - JRSofty
如何仅获取未读邮件,似乎搜索方法现在不接受标志。 - Syam Danda

3
我认为这可能有助于访问已读/未读/最近的邮件,根据您的需要更改您的变量。
// search for all "unseen" messages

Flags seen = new Flags(Flags.Flag.SEEN);// try changing this SEEN to RECENT 

// set it true or false for seen & unseen mail

FlagTerm unseenFlagTerm = new FlagTerm(seen, false)
Message messages[] = inbox.search(unseenFlagTerm);

2

JavaMail提供了一系列的Message对象。这些消息按照接收顺序排列。如果您想要先查看最近收到的邮件,请按照相反的顺序遍历数组。如果您想要先查看最近发送的邮件,您需要对数组进行排序,如其他答案所述。


我想我知道他的问题是什么。至少听起来像我曾经遇到过的一个问题:如果你想在用户操作后及时更新屏幕,那么大多数IMAP服务器的FETCH响应顺序都不好。"最高UID优先"比"最低UID优先"更好。但这不是Javamail可以解决的问题。 - arnt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接