Отправка строки в виде вложения с использованием javamail приводит к дублированию содержимого

#java #jakarta-mail

#java #джакарта-почта

Вопрос:

Я изо всех сил пытаюсь отправить csv-файл через javamail.

Поскольку содержимое невелико, я вручную сконструировал данные в формате CSV, сохранил в памяти и передал как ByteArrayDataSource MimeMessageHelper . Однако полученный файл странным образом удваивает содержимое.

Двойное содержимое

Код довольно стандартный:

 // mail sender
try {
            MimeMessage mail = javaMailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(mail, true, "UTF-8");
            helper.setSubject(mailObj.getMailSubject());
            helper.setFrom(mailObj.getMailFrom());
            helper.setTo(mailObj.getMailTo());
            Mail.Attachment attachment = mailObj.getAttachment();
            if (attachment != null) helper.addAttachment(attachment.getFilename(),
                                                         attachment.getDataSource());
            javaMailSender.send(helper.getMimeMessage());
        } catch (Exception e) {
            log.error("Cannot send email "   mailObj.toString(), e);
        }
 
 DataSource createDataSource(Data originalData) throws IOException {
        try (StringWriter out = new StringWriter(); PrintWriter pw = new PrintWriter(out) {
            @Override
            public void println() {
                write(LINE_SEP);
            }
        }) {
            pw.write('uFEFF'); // Write BOM
            pw.println(HEADERS);
            for (AppointmentBookingEvent details : appointments) {
                // Concatenate the data with PrintWriter.println(...);
            }
            return new ByteArrayDataSource(out.toString().getBytes(StandardCharsets.UTF_8), "text/csv");
        }
    }
 

Я заметил, что метод DataSource.getInputStream() вызывается дважды внутренними функциями отправителя. Это случайно не было причиной?

Комментарии:

1. Я попытался выполнить запись во временный файл, затем отправленный как FileDataSource , но дублирование сохраняется, хотя с временным файлом все было в порядке.

Ответ №1:

Похоже, проблема возникла MimeMessageHelper . Я не мог точно определить, где именно, но проблема исчезла, когда я явно сконструировал основные части mail.

             MimeMessage mail = javaMailSender.createMimeMessage();
            mail.setFrom(new InternetAddress(mailObj.getMailFrom()));
            mail.setRecipients(Message.RecipientType.TO, InternetAddress.parse(mailObj.getMailTo()));
            mail.setSubject(mailObj.getMailSubject());
            Multipart multipart = new MimeMultipart();
            BodyPart messageBodyPart = new MimeBodyPart();
            messageBodyPart.setContent(getContentFromTemplate(mailObj.getModel(), mailObj.getLang(), mailObj.getTemplateName()), "text/html; charset=UTF-8");
            multipart.addBodyPart(messageBodyPart);
            Mail.Attachment attachment = mailObj.getAttachment();
            if (attachment != null) {
                BodyPart attachmentBodyPart = new MimeBodyPart();
                attachmentBodyPart.setFileName(attachment.getFilename());
                attachmentBodyPart.setDisposition(Part.ATTACHMENT);
                attachmentBodyPart.setDataHandler(new DataHandler(attachment.getDataSource()));
                multipart.addBodyPart(attachmentBodyPart);
            }
            mail.setContent(multipart);
            javaMailSender.send(mail);