【发布时间】:2018-10-12 10:01:40
【问题描述】:
下一个问题我需要帮助:
我需要在 Gmail 上使用非 ascii 字符进行搜索(西里尔字母(例如 俄语 或 乌克兰语))。当我使用标准 IMAP SEARCH 命令时,我收到一个错误:
A12 SEARCH CHARSET UTF-8 SUBJECT "текст" ALL
A12 BAD Could not parse command
在Java中,它看起来像
Message[] foundMessages = imapFolder.search(new SubjectTerm("текст"));
我在这里找到了一些帮助 IMAP search for non-ascii characters。使用 openssl s_client -crlf -connect imap.gmail.com:993 我已经通过 Terminal 连接到我的邮箱,并且收到了下一个结果:
A12 SEARCH CHARSET UTF-8 X-GM-RAW {10}
+ go ahead
текст
* SEARCH 226
A13 OK SEARCH completed (Success)
主要问题 - 如何在 Java 中实现?
更新
我对 JavaMail 源代码做了一些研究。我找到了下一行
// if server supports UTF-8, enable it for client use
// note that this is safe to enable even if mail.mime.allowutf8=false
if (p.hasCapability("UTF8=ACCEPT") || p.hasCapability("UTF8=ONLY"))
p.enable("UTF8=ACCEPT");
}
我们从 gmail 服务器接收下一个功能
A1 LOGIN test@gmail.com password
* CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN
X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE ENABLE MOVE CONDSTORE ESEARCH
UTF8=ACCEPT LIST-EXTENDED LIST-STATUS
LITERAL-SPECIAL-USE APPENDLIMIT=35651584
因此,JavaMail 自动将mail.mime.allowutf8 设置为true。但在这种情况下,JavaMail 使用下一个命令进行搜索
C6 SEARCH CHARSET UTF-8 X-GM-RAW "текст" ALL
我收到一个错误
C6 BAD Could not parse command
Argument.nastring(byte[] bytes, Protocol protocol, boolean doQuote)
boolean utf8 = protocol.supportsUtf8(); --> 对于 Gmail 来说确实如此。这就是 JavaMail 不使用文字的原因。
byte b;
for (int i = 0; i < len; i++) {
b = bytes[i];
if (b == '\0' || b == '\r' || b == '\n' ||
(!utf8 && ((b & 0xff) > 0177))) {
// NUL, CR or LF means the bytes need to be sent as literals
literal(bytes, protocol);
return;
}
if (b == '*' || b == '%' || b == '(' || b == ')' || b == '{' ||
b == '"' || b == '\\' ||
((b & 0xff) <= ' ') || ((b & 0xff) > 0177)) {
quote = true;
if (b == '"' || b == '\\') // need to escape these characters
escape = true;
}
}
我测试了其他没有UTF8=ACCEPT 的电子邮件提供商。一切正常。
K11 SEARCH CHARSET UTF-8 SUBJECT {10}
+ continue
текст ALL
* SEARCH 1194
K11 OK SEARCH completed
【问题讨论】:
标签: jakarta-mail imap