代码之家  ›  专栏  ›  技术社区  ›  Julian

Javax。试图使用gmail的imap扩展访问X-GM-MSGID的邮件

  •  1
  • Julian  · 技术社区  · 7 年前

    我正在尝试使用 X-GM-EXT-1 谷歌在javax中为gmail创建的IMAP扩展。邮政此处为文档 https://developers.google.com/gmail/imap/imap-extensions

    我特别想获取一系列 X-GM-MSGID 标题使用 UID FETCH 语法扩展。

    我正在使用的java代码: (我在命令中使用的是真实的UID,但为了举例说明,我粘贴的范围与doc的示例相同)

    Response[] r = (Response[]) folder.doCommand(protocol -> protocol.command("UID FETCH 1:4 (X-GM-MSGID)", null));
    

    这种声明imap命令的方式对我来说适用于其他扩展(特别是ESEARCH)

    这是文档中的一个片段,这是我实验的源材料。

    a008 FETCH 1:4 (X-GM-THRID)
    * 1 FETCH (X-GM-THRID 1278455344230334865)
    * 2 FETCH (X-GM-THRID 1266894439832287888) 
    * 3 FETCH (X-GM-THRID 1266894439832287888)
    * 4 FETCH (X-GM-THRID 1266894439832287888)
    a008 OK FETCH (Success)
    

    我在等我的 Response[] 对象包含多个响应行,每个响应行对应一条提取的消息,然后是标记的 OK FETCH (Success) 线然而,我的回答中只有一句话是 A57 OK Success 。我不确定这意味着什么,也许是javax。邮件并没有像我预期的那样做,或者可能需要做一些特定的事情来访问完整的响应。

    是否有更好的方法或更正确的方法来使用此扩展?

    编辑:

    这里是一个可执行的示例,它将我描述的输出打印到控制台。一个要求是,需要传入的通过imap存储验证的gmail收件箱必须在文件夹中至少有一条消息,以便ESEARCH能够识别要使用的最小uid。

    private void MCVE(IMAPStore store) throws MessagingException {
        IMAPFolder inbox = (IMAPFolder) store.getFolder("Inbox");
        inbox.open(Folder.READ_ONLY, ResyncData.CONDSTORE);
    
        Response[] minUidResponse = (Response[]) inbox.doCommand(
                protocol -> protocol.command("UID SEARCH RETURN (min max count all) 1:*", null)
        );
    
        String minUid = "";
        for (Response aLine : minUidResponse) {
            String str = aLine.toString();
            if (str.startsWith("* ESEARCH")) {
                List<String> tokens = Arrays.asList(str.split(" "));
                minUid = tokens.get(tokens.indexOf("MIN") + 1);
            }
        }
    
        final String finalMinUid = minUid; // lambas need effectively final stuff
        Response[] gidResponse = (Response[]) inbox.doCommand(
                protocol -> protocol.command("UID FETCH " + finalMinUid + " (X-GM-MSGID)", null)
        );
    
        System.out.println("Printing result of X-GM-MSGID uid fetch");
        for (Response r : gidResponse) {
            System.out.println(r.toString());
        }
    }
    

    编辑2:

    在邮件会话中启用调试模式后,我看到一个异常被抛出并从常规输出中隐藏。

     DEBUG IMAP: connection available -- size: 1
     A4 ENABLE CONDSTORE
     * ENABLED
     A4 OK Success
     A5 EXAMINE Inbox (CONDSTORE)
     * FLAGS (\Answered \Flagged \Draft \Deleted \Seen $NotPhishing $Phishing)
     * OK [PERMANENTFLAGS ()] Flags permitted.
     * OK [UIDVALIDITY 1] UIDs valid.
     * 7 EXISTS
     * 0 RECENT
     * OK [UIDNEXT 23071] Predicted next UID.
     * OK [HIGHESTMODSEQ 1327692]
     A5 OK [READ-ONLY] Inbox selected. (Success)
     A6 UID SEARCH RETURN (min max count all) 1:*
     * ESEARCH (TAG "A6") UID COUNT 7 MIN 23064 MAX 23070 ALL 23064:23070
     A6 OK SEARCH completed (Success)
     A7 UID FETCH 23064 (X-GM-MSGID)
     * 1 FETCH (X-GM-MSGID 1594485864262816838 UID 23064 MODSEQ (1327330))
     DEBUG IMAP: ignoring bad response, THROW:
     com.sun.mail.iap.ParsingException: error in FETCH parsing, unrecognized item at index 11, starts with "X-GM-MSGID 159448586..."
         at com.sun.mail.imap.protocol.FetchResponse.parse(FetchResponse.java:219)
         at com.sun.mail.imap.protocol.FetchResponse.<init>(FetchResponse.java:96)
         at com.sun.mail.imap.protocol.IMAPProtocol.readResponse(IMAPProtocol.java:392)
         at com.sun.mail.iap.Protocol.command(Protocol.java:354)
         at my.package.ImapSync.lambda$MCVE$5(ImapSync.java:85)
         at com.sun.mail.imap.IMAPFolder.doProtocolCommand(IMAPFolder.java:3784)
         at com.sun.mail.imap.IMAPFolder.doCommand(IMAPFolder.java:3734)
         at my.package.ImapSync.MCVE(ImapSync.java:84)
         ...
     A7 OK Success
    
    
     Printing result of X-GM-MSGID uid fetch
     A7 OK Success
    

    编辑3:

    我使用的javamail版本是1.5.5。我将尝试升级到1.6.1,看看这是否会改变服务器响应的解析方式。

    升级到1.6.1后,对同一示例代码进行快速测试,结果仍然相同。所以这并不是随着时间而“固定”的。(引用,因为我不知道javamail是否有bug,或者我是否滥用了它)

    1 回复  |  直到 7 年前
        1
  •  1
  •   Bill Shannon    7 年前

    你做得很艰难。只需使用 "gimap" protocol provider for JavaMail