Не удалось разобрать это тело сообщения MIME из нескольких частей в Java - PullRequest
4 голосов
/ 06 октября 2011

Я не пишу почтовое приложение, поэтому у меня нет доступа ко всем заголовкам и тому подобному. Все, что у меня есть, это что-то вроде блока в конце этого вопроса. Я пытался использовать JavaMail API, чтобы разобрать это, используя что-то вроде

Session s = Session.getDefaultInstance(new Properties());
InputStream is = new ByteArrayInputStream(<< String to parse >>);
MimeMessage message = new MimeMessage(s, is);
Multipart multipart = (Multipart) message.getContent();

Но это просто говорит мне, что message.getContent - это String, а не Multipart или MimeMultipart. Кроме того, мне не нужны все накладные расходы на весь API JavaMail, мне просто нужно разобрать текст на части. Вот пример:

This is a multi-part message in MIME format.\n\n------=_NextPart_000_005D_01CC73D5.3BA43FB0\nContent-Type: text/plain;\n\tcharset="iso-8859-1"\nContent-Transfer-Encoding: quoted-printable\n\nStuff:\n\n            Please read this stuff at the beginning of each week.  =\nFeel free to discuss it throughout the week.\n\n\n--=20\n\nMrs. Suzy M. Smith\n555-555-5555\nsuzy@suzy.com\n------=_NextPart_000_005D_01CC73D5.3BA43FB0\nContent-Type: text/html;\n\tcharset="iso-8859-1"\nContent-Transfer-Encoding: quoted-printable\n\n\n\n\n\n\n\n\n\nStuff:</P>\n           =20\nPlease read this stuff at the beginning of each =\nweek.  Feel=20\nfree to discuss it throughout the week.</P>\n<BR>-- <BR><BR>Mrs. Suzy M. Smith<BR>555-555-5555<BR>suzy@suzy.com\n\n------=_NextPart_000_005D_01CC73D5.3BA43FB0--\n\n

Ответы [ 4 ]

7 голосов
/ 06 октября 2011

Сначала я взял ваше примерное сообщение и заменил все вхождения \n на новые строки и \t на вкладки.

Затем я загрузил JAR-файлы из проекта Mime4J , подпроекта Apache James и выполнил разбор GUI пример org.apache.james.mime4j.samples.tree.MessageTree с преобразованным сообщением выше в качестве ввода.И, видимо, Mime4J смог проанализировать сообщение и извлечь часть HTML-сообщения.

6 голосов
/ 06 октября 2011

В опубликованном вами тексте есть несколько ошибок.

Это недопустимый мим из нескольких частей. Проверьте ссылку на Википедию , которая, хотя и ненормативна, все же верна.

Граница пантомимы не определена. Из примера википедии: Content-Type: multipart/mixed; boundary="frontier" показывает, что граница является "границей". В вашем примере "---- = _ NextPart_000_005D_01CC73D5.3BA43FB0" - это граница, но это можно определить только путем сканирования текста (, т. Е. , мим искажен). Вы должны указать дураку, который передает вам содержимое MIME, вам также необходимо знать граничное значение MIME, которое не определено в заголовке сообщения. Если вы получите все тело сообщения, вам будет достаточно, потому что тело сообщения начинается с MIME-Version: 1.0, за которым следует Content-Type: multipart/mixed; boundary="<i>frontier</i>", где frontier будет заменено значением границы для закодированного mime. .

Если человек, отправляющий тело, является дураком (изменен с обезьяны, потому что обезьяна слишком осуждающая - мой плохой DwB), и не будет (скорее всего, не знает, как) отправить полную body, вы можете получить границу, отсканировав текст на наличие строки, которая начинается и заканчивается на «-» ( т.е. --boundary--). Обратите внимание, что я упомянул «линию». Терминальная граница на самом деле "--boundary - \ n".

Наконец, материал, который вы опубликовали, состоит из 2 частей. Первая часть, кажется, определяет замены, которые будут иметь место во второй части. Если это так, то Content-Type: первой части, вероятно, должен быть чем-то отличным от «text / plain». Возможно "название компании / определение замещения" или что-то в этом роде. Это позволит использовать несколько (как в будущих улучшениях) форматов замены.

4 голосов
/ 16 августа 2012

Может создать MimeMultipart из http-запроса.

javax.mail.internet.MimeMultipart m = new MimeMultipart(new ServletMultipartDataSource(httpRequest));

public class ServletMultipartDataSource implements DataSource {
    String contentType;
    InputStream inputStream;
    public ServletMultipartDataSource(ServletRequest request) throws IOException {
        inputStream = new SequenceInputStream(new ByteArrayInputStream("\n".getBytes()), request.getInputStream());
        contentType = request.getContentType();
    }
    public InputStream getInputStream() throws IOException {
        return inputStream;
    }
    public OutputStream getOutputStream() throws IOException {
        return null;
    }
    public String getContentType() {
        return contentType;
    }
    public String getName() {
        return "ServletMultipartDataSource";
    }
}

Для получения отправленного параметра формы необходимо проанализировать заголовки BodyPart:

public String getStringParameter(String name) throws MessagingException, IOException {
    for (int i = 0; i < getCount(); i++) {
        BodyPart bodyPart = m.getBodyPart(i);
        String[] nameHeader = bodyPart.getHeader("Content-Disposition");
        if (nameHeader != null && content instanceof String) {
            for (String bodyName : nameHeader) {
                if (bodyName.contains("name=\"" + name + "\"")) return String.valueOf(bodyPart.getContent());
            }
        }
    }
    return null;
}
2 голосов
/ 02 ноября 2012

Если вы используете javax.servlet.http.HttpServlet для получения сообщения, вам придется использовать HttpServletRequests.getHeaders для получения значения типа содержимого заголовка HTTP.Затем вы будете использовать org.apache.james.mime4j.stream.MimeConfig.setHeadlessParsing, чтобы установить MimeConfig с информацией, чтобы он мог правильно обрабатывать сообщение mime.

Похоже, что вы используете HttpServletRequest.getInputStream для чтения содержимого запроса.Возвращенный входной поток имеет содержимое сообщения только после заголовков HTTP (завершается пустой строкой).Вот почему вы должны извлечь тип содержимого из заголовков HTTP и передать его анализатору с помощью setHeadlessParsing.

...