JavaMail. Поиск IMAP с использованием буквального слова в Gmail

Мне нужна помощь со следующим вопросом:

Мне нужно выполнить поиск, используя символы, отличные от 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
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
277
1

Ответы 1

Если взглянуть на исходный код, он должен работать, если вы используете 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 станет легальным синтаксисом, который должен делать то, что вы хотите.

Я попробовал твой ответ. Но я все равно получаю сообщение об ошибке. 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.

Den 02.05.2018 14:14

Вы обнаружите, что поиск по запросу «текст» не выполняется с той же ошибкой. Перед поиском необходимо выбрать почтовый ящик.

arnt 02.05.2018 14:18

Мне жаль. Забыл сделать A5 SELECT INBOX. Теперь ваш код работает

Den 02.05.2018 14:20

Другие вопросы по теме