JavaMail в Google App Engine отправляет электронное письмо в формате HTML с вложениями - игнорирует первое вложение

Я использую Java в Google App Engine и пытаюсь отправить электронное письмо с несколькими вложениями.

Что я нахожу, так это то, что по какой-то причине отсутствует первое вложение. По сути, если filesToAttach содержит 1 файл, то вложений не будет. Если filesToAttach содержит 4 файла - A, B, C и D, то к пришедшему сообщению будут прикреплены файлы B, C и D. Действительно странно.

Код, который я использую, приведен ниже. Любые предложения о том, как исправить это, очень ценятся.

Вывод, генерируемый вызовами log.info, показывает правильное количество прикрепленных файлов.

    Properties props = new Properties();
    Session session = Session.getInstance(props);
    Message message = new MimeMessage(session);
    String fromEmail = "admin@" + ApiProxy.getCurrentEnvironment().getAppId() + ".appspotmail.com";
    message.setFrom(new InternetAddress(fromEmail, "MyApp Admin"));
    message.addRecipients(Message.RecipientType.BCC, addresses);
    message.setSubject(subject);
    MimeMultipart multipart = new MimeMultipart();

    MimeBodyPart htmlPart = new MimeBodyPart();
    htmlPart.setContent(htmlBody, "text/html");
    multipart.addBodyPart(htmlPart);

    for(FileToAttach fileToAttach : filesToAttach) {
      MimeBodyPart fileMimeBodyPart = new MimeBodyPart();
      DataSource dataSource = new ByteArrayDataSource(fileToAttach.getContents(), "application/octet-stream");
      fileMimeBodyPart.setDataHandler(new DataHandler(dataSource));
      fileMimeBodyPart.setFileName(fileToAttach.getFileName());
      log.info("attaching file " + fileToAttach.getFileName() + " of " + fileToAttach.getContents().length + " bytes");
      multipart.addBodyPart(fileMimeBodyPart);
    }

    message.setContent(multipart);
    log.info("the multipart contains " + multipart.getCount() + " parts and isComplete = " + multipart.isComplete());
    Transport.send(message);
    log.info("called Transport.send");

person BenTaylor    schedule 26.01.2014    source источник
comment
Уродливым обходным решением было бы поместить пустой фиктивный файл в качестве первой записи в filesToAttach ;-) Это дает желаемый результат, в то время как вы тратите больше времени на поиск правильного решения. У меня нет опыта работы с составной почтой, но симптомы предполагают, что первое вложение может быть объединено с htmlPart, но не отображаться, потому что оно не отформатировано в формате html. Попробуйте добавить что-то, что будет ограничивать конец тела html, прежде чем добавлять вложения файлов.   -  person Martin Berends    schedule 26.01.2014
comment
Я не вижу ничего явно плохого. Возможно, вы захотите установить расположение вложений (метод setDisposition) или упростить свой код с помощью метода attachFile. Кроме того, непосредственно перед Transport.send выполните message.writeTo(new FileOutputStream(msg.txt)) и посмотрите, есть ли в msg.txt все вложения. Если ничего из этого не дает подсказок, возможно, Google App Engine имеет неработающую версию JavaMail.   -  person Bill Shannon    schedule 26.01.2014
comment
Возможно, решение этой проблемы (которое я наблюдал на App Engine) может помочь. Хотя это относится к multipart/alternative, подобный эффект может быть и с вложениями. Возможно, реализация App Engine JavaMail предполагает, что часть text/plain будет сопровождать тело text/html?   -  person tx802    schedule 27.01.2014
comment
Ага. Я думаю, что это может быть правильно, потому что, если я прикреплю два изображения, MIME-тип первого будет text/plain. Кажется, я обошел это, выполнив fileMimeBodyPart.SetHeader("Content-Type", "image/jpeg") (или application/octet-stream). Но может быть более элегантным решением сделать setText и для составной части, я попробую. Большое спасибо за предложение   -  person BenTaylor    schedule 27.01.2014