Разбор Multipart / смешанный с Multipart / альтернативным телом в java

Я получаю электронные письма от клиента, где они вложили многостраничное / альтернативное сообщение внутри многостраничного / смешанного сообщения. Когда я получаю тело сообщения, он просто возвращает многостраничный / альтернативный уровень, когда то, что я действительно хочу, - это часть text/html, которая содержится в многостраничной/альтернативе.

Я просмотрел javadocs для javax.mail и я не могу найти простой способ получить тело bodypart, которое само по себе является составным или пропустить первый multipart / mixed и в многотомных/альтернативное тело, чтобы прочитать текст/HTML и текстовую части.

структура электронной почты выглядит так:

...
Content-Type: multipart/mixed; 
    boundary="----=_Part_19487_1145362154.1418138792683"

------=_Part_19487_1145362154.1418138792683
Content-Type: multipart/alternative; 
    boundary="----=_Part_19486_1391901275.1418138792683"

------=_Part_19486_1391901275.1418138792683
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset=ISO-8859-1

...

------=_Part_19486_1391901275.1418138792683
Content-Transfer-Encoding: 7bit
Content-Type: text/html; charset=ISO-8859-1

...

------=_Part_19486_1391901275.1418138792683--

------=_Part_19487_1145362154.1418138792683--

это набросок кода, используемого для анализа писем:

Message [] found = fldr.search(searchCondition);           
for (int i = 0; i < found.length; i++) {
    Message m = found[i];
    Object o = m.getContent();
    if (o instanceof Multipart) {
        log.info("**This is a Multipart Message.  ");
        Multipart mp = (Multipart)o;
        log.info("The Multipart message has " + mp.getCount() + " parts.");
        for (int j = 0; j < mp.getCount(); j++) {
            BodyPart b = mp.getBodyPart(j);

            // Loop if the content type is multipart then get the content that is in that part,
            // make it the new container and restart the loop in that part of the message.
            if (b.getContentType().contains("multipart")) {
                mp = (Multipart)b.getContent();
                j = 0;
                continue;
            }

            log.info("This content type is " + b.getContentType());

            if(!b.getContentType().contains("text/html")) {
                continue;
            }

            Object o2 = b.getContent();
            if (o2 instanceof String) {
                <do things with content here>
            }
        }
    }
}

Кажется, что он продолжает останавливаться на второй границе и не анализирует ничего дальше. В случае вышеуказанного сообщения он останавливается на границе="----=_Part_19486_1391901275.1418138792683" и никогда не попадает в текст сообщения.

2 ответов


в этот блок :

if (b.getContentType().contains("multipart"))
{
    mp = (Multipart)b.getContent();
    j = 0;
    continue;
}

установить j до 0 и попросите цикл продолжить, надеясь, что он снова начнется с нуля. Но операция приращения j++ придет раньше, и ваш цикл начнется с 1, а не 0.

Set j -1, чтобы решить вашу проблему.

if (b.getContentType().contains("multipart"))
{
    mp = (Multipart)b.getContent();
    j = -1;
    continue;
}

я протестировал ваш код и не для меня.

в моем случае, b.getContentType() возвращает все символы верхнего регистра (например, "TEXT/HTML; charset=UTF-8"). Поэтому я преобразовал это в нижний регистр, и это сработало.

String contentType=b.getContentType().toLowerCase(Locale.ENGLISH);

if(!contentType.contains("text/html")) {
   continue;
}