Мне нужна помощь со следующим вопросом:
Мне нужно выполнить поиск, используя символы, отличные от ascii, на Gmail (Кириллица (например, русский или украинец)). Когда я использую стандартную команду ПОИСК IMAP, я получаю сообщение об ошибке:
A12 SEARCH CHARSET UTF-8 SUBJECT "текст" ALL
A12 BAD Could not parse command
В Java это выглядит как
Message[] foundMessages = imapFolder.search(new SubjectTerm("текст"));
Я нашел здесь помощь Поиск IMAP для символов, отличных от ascii. Используя openssl s_client -crlf -connect imap.gmail.com:993
, я подключился к своему почтовому ящику через Терминал и получил следующие результаты:
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 [email protected] 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
Я пошел дальше и исследовал https://github.com/javaee/javamail/blob/52e04fc107d0b83fa794e6f622f7c76b9e85e395/mail/src/main/java/com/sun/mail/iap/Argument.java#L313
Argument.nastring(byte[] bytes, Protocol protocol, boolean doQuote)
логическое 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
Если взглянуть на исходный код, он должен работать, если вы используете javamail 1.6.1. Возможно, вам потребуется установить для свойства mail.mime.allowutf8
значение true.
Более подробно: 1.6 добавляет поддержку адресов электронной почты Unicode, таких как jøran@blåbærsyltetøy.gulbrandsen.priv.no, что в качестве побочного эффекта упорядочивает использование UTF8 почти повсеместно. Когда вы подключаетесь к gmail, javamail 1.6 должен отправить команду входа в систему, а затем автоматически одну в соответствии со строками a04 enable utf8=accept
, и как только gmail подтвердит utf8 = accept, a12 search subject "текст" all
станет легальным синтаксисом, который должен делать то, что вы хотите.
Вы обнаружите, что поиск по запросу «текст» не выполняется с той же ошибкой. Перед поиском необходимо выбрать почтовый ящик.
Мне жаль. Забыл сделать A5 SELECT INBOX
. Теперь ваш код работает
Я попробовал твой ответ. Но я все равно получаю сообщение об ошибке.
A1 OK [email protected] authenticated (Success) a04 enable utf8=accept * ENABLED UTF8=ACCEPT a04 OK Success a12 search subject "текст" all a12 BAD SEARCH not allowed now.