JavaMail IMAP 消息内容 SSL/NON SSL

Posted

技术标签:

【中文标题】JavaMail IMAP 消息内容 SSL/NON SSL【英文标题】:JavaMail IMAP message content SSL/NON SSL 【发布时间】:2014-02-12 14:15:01 【问题描述】:

我在 JavaMail 中的 IMAP 遇到了奇怪的问题。

我已经知道很多关于 JavaMail 的知识,而且我也知道在哪里可以找到问题/答案,但是我找不到解决这个问题的方法。

我有 IMAP 通道,我可以在该通道上设置 SSL 启用或禁用。 当我创建新的电子邮件消息(比如,主题:“TEST”,正文:“HELLO”)并从 Thunderbird 客户端发送它,以便能够使用我的 IMAP 频道下载它时,事情变得很奇怪。

在启用 SSL 时,一切正常。 (在我的 IMAP 频道中)我从电子邮件文件夹中收到消息,成功连接到商店后,然后我从此消息中获取内容()(它始终是字符串类型,而不是 MimeMultipart 或 Multipart),输出为“HELLO”。

但是,在 SSL DISABLED 上,一切正常,但我收到不同的正文。看起来整个消息都已解析(如下所示)

message.getContent().toString();使用 SSL

HELLO

message.getContent().toString();不使用 SSL

Return-Path: and@127.0.0.1
Received: from [127.0.0.1] (localhost [127.0.0.1]) by PC ; Wed, 22 Jan 2014 13:23:17 +0100
Message-ID: <52DFB835.9020300@127.0.0.1>
Date: Wed, 22 Jan 2014 13:23:17 +0100
From: "and@127.0.0.1" <and@127.0.0.1>
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:17.0) Gecko/20130509 Thunderbird/17.0.6
MIME-Version: 1.0
To: and@127.0.0.1
Subject: TEST
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit

有人知道发生了什么吗?以下是我的代码片段(向您展示最重要的部分:

// properties used to create session 
String protocol = useSSL ? "imaps" : imap";

properties.setProperty("mail.store.protocol", protocol);
properties.setProperty("mail." + protocol + ".host", ...);
properties.setProperty("mail." + protocol + ".user", ...);
properties.setProperty("mail." + protocol + ".port", ...);
properties.setProperty("mail." + protocol + ".password", ...);

// only when using ssl
properties.setProperty("mail.imaps.auth", "true");
properties.setProperty("mail.imaps.starttls.enable", "true");
properties.setProperty("mail.imaps.ssl.checkserveridentity", "true");
properties.setProperty("javax.net.ssl.trustStore", ...);
properties.setProperty("javax.net.ssl.trustStorePassword", ...);

// get store and other important things
Store store = this.session.getStore(protocol);
Folder folder = store.getFolder("INBOX");
folder.open(Folder.READ_WRITE);
Message[] newMessages = folder.getMessages();
for (Message newMessage : newMessages) 
  Object o = newMessage.getContent();
  System.out(o.toString()); // should write "HELLO", but instead it parses whole message (only on NON SSL MODE!)

// 编辑:添加调试信息 // 编辑 2:调试信息现在包含获取文件夹的完整详细信息,使用 CONTENT_INFO, FLAGS, ENVELOPE

DEBUG: getProvider() returning javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Sun Microsystems, Inc]
DEBUG: mail.imap.fetchsize: 16384
DEBUG: protocolConnect returning false, host=127.0.0.1, user=and@127.0.0.1, password=<null>
* OK IMAPrev1
A0 CAPABILITY
* CAPABILITY IMAP4 IMAP4rev1 CHILDREN IDLE QUOTA SORT ACL NAMESPACE RIGHTS=texk
A0 OK CAPABILITY completed
DEBUG: protocolConnect login, host=127.0.0.1, user=and@127.0.0.1, password=<non-null>
A1 LOGIN and@127.0.0.1 password
A1 OK LOGIN completed
DEBUG: connection available -- size: 1
A2 SELECT INBOX
* 1 EXISTS
* 0 RECENT
* FLAGS (\Deleted \Seen \Draft \Answered \Flagged)
* OK [UIDVALIDITY 1378802425] current uidvalidity
* OK [UNSEEN 50167] unseen messages
* OK [UIDNEXT 50168] next uid
* OK [PERMANENTFLAGS (\Deleted \Seen \Draft \Answered \Flagged)] limited
A2 OK [READ-WRITE] SELECT completed
A3 SEARCH UNSEEN ALL
* SEARCH 1
A3 OK Search completed
A4 FETCH 1 (BODYSTRUCTURE)
* 1 FETCH (UID 50167 BODYSTRUCTURE ("TEXT" "PLAIN" ("CHARSET" "UTF-8") NIL "test" "7bit" 7 2))
A4 OK FETCH completed
A5 FETCH 1 (BODY[TEXT]<0.7>)
* 1 FETCH (UID 50167 ENVELOPE ("Tue, 28 Jan 2014 15:08:59 +0100" "test" (("and@127.0.0.1" NIL "and" "127.0.0.1")) (("and@127.0.0.1" NIL "and" "127.0.0.1")) (("and@127.0.0.1" NIL "and" "127.0.0.1")) (("and@127.0.0.1" NIL "and" "127.0.0.1")) NIL NIL NIL "<52E7B9FB.2030409@127.0.0.1>") BODY[HEADER] 479
Return-Path: and@127.0.0.1
Received: from [127.0.0.1] (localhost [127.0.0.1]) by A-PC ; Tue, 28 Jan 2014 15:08:59 +0100
Message-ID: <52E7B9FB.2030409@127.0.0.1>
Date: Tue, 28 Jan 2014 15:08:59 +0100
From: "and@127.0.0.1" <and@127.0.0.1>
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:17.0) Gecko/20130509 Thunderbird/17.0.6
MIME-Version: 1.0
To: and@127.0.0.1
Subject: test
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit

 BODY[TEXT]<0> 7
HELLO
)
A5 OK FETCH completed
A6 FETCH 1 (FLAGS)
* 1 FETCH (UID 50167 FLAGS (\Seen))
A6 OK FETCH completed
A7 FETCH 1 (ENVELOPE INTERNALDATE RFC822.SIZE FLAGS BODYSTRUCTURE)
* 1 FETCH (UID 50167 RFC822.SIZE 462 FLAGS (\Seen) INTERNALDATE "28-Jan-2014 15:08:59 +0100" ENVELOPE ("Tue, 28 Jan 2014 15:08:59 +0100" "test" (("and@127.0.0.1" NIL "and" "127.0.0.1")) (("and@127.0.0.1" NIL "and" "127.0.0.1")) (("and@127.0.0.1" NIL "and" "127.0.0.1")) (("and@127.0.0.1" NIL "and" "127.0.0.1")) NIL NIL NIL "<52E7B9FB.2030409@127.0.0.1>") BODYSTRUCTURE ("TEXT" "PLAIN" ("CHARSET" "UTF-8") NIL "test" "7bit" 7 2))
A7 OK FETCH completed
A8 STORE 1 +FLAGS (\Seen)
* 1 FETCH (FLAGS (\Seen) UID 50167)
A8 OK STORE completed
A9 CLOSE
A9 OK CLOSE completed
DEBUG: added an Authenticated connection -- size: 1
IMAP DEBUG: IMAPProtocol noop
A10 NOOP
A10 OK NOOP completed
DEBUG: connection available -- size: 1
A11 SELECT INBOX
* 1 EXISTS
* 0 RECENT
* FLAGS (\Deleted \Seen \Draft \Answered \Flagged)
* OK [UIDVALIDITY 1378802425] current uidvalidity
* OK [UIDNEXT 50168] next uid
* OK [PERMANENTFLAGS (\Deleted \Seen \Draft \Answered \Flagged)] limited
A11 OK [READ-WRITE] SELECT completed
A12 SEARCH UNSEEN ALL
* SEARCH
A12 OK Search completed
A13 CLOSE
A13 OK CLOSE completed
DEBUG: added an Authenticated connection -- size: 1
IMAP DEBUG: IMAPProtocol noop
A14 NOOP
A14 OK NOOP completed
A15 LOGOUT
* BYE Have a nice day
A15 OK Logout completed
DEBUG: IMAPStore connection dead
DEBUG: IMAPStore cleanup, force false
DEBUG: IMAPStore cleanup done

服务器是 hMailServer,在 127.0.0.1 上运行,启用了 SSL 和 NONSSL 端口。

看来,我只得到邮件的标题,而不是正文..

感谢您的任何建议,祝您有美好的一天!

【问题讨论】:

在 SSL 和非 SSL 端口上运行的服务器软件是否相同? 如果打开 JavaMail 会话调试,协议跟踪会显示什么?您在每种情况下都使用什么类型的服务器? 我以帖子编辑的形式回复 尝试不带八位字节说明符的 FETCH,即只使用 BODY.PEEK[TEXT],不带 我刚刚添加了抓取调试,使用了 FetchProfile 中的三个项目。很奇怪,我在调试信息中得到了 BODY,但在消息内容中没有.. 【参考方案1】:

我解决了这个问题。我遇到的错误与“无法加载 BODYSTRUCTURE”错误有关(以下链接 - 了解 IMAP 复杂性)。

https://java.net/projects/javamail/pages/Exchange

http://www.oracle.com/technetwork/java/javamail/faq/index.html#imapserverbug

为了获得正确的正文消息,必须做的就是使用 MimeMessage 构造函数创建消息的副本。

// newMessages - it is array of messages from the mail inbox
// create copy of the message using MimeMessage constructor
MimeMessage message = new MimeMessage(newMessages[0]); // without it, the content was as in my first post
// get content from the mssage
Object messageContent = message.getContent();
// output it as a string
System.out.println(messageContent.toString());

问题解决了,现在我得到了我想要的和我应该得​​到的。唯一剩下的是,为什么 SSL 和 NONSSL 消息内容之间存在差异?也许是防病毒问题?

感谢您的帮助和关注。

祝你有美好的一天。

【讨论】:

什么是MimeMessage message = new MimeMessage(newMessages[0]);?我花了几个小时来调试这个......

以上是关于JavaMail IMAP 消息内容 SSL/NON SSL的主要内容,如果未能解决你的问题,请参考以下文章

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

Javamail - 如何处理大附件?

使用GMail客户端和JavaMail访问GMail(通过pop3)

javaMail

Javamail

JavaMail