Переслать электронное письмо (прочитанное с помощью JavaMailApi) с вложениями с помощью apache common java api

Я читаю сообщения из веб-почты Outlook и получаю список сообщений ('javax.mail.Message'). Теперь я хочу переслать эти сообщения на другой адрес электронной почты с помощью программы Java.

    private void sendTestMail(String from, String subject, String sentDate, Object object, Message message)
            throws EmailException, Exception {

        MultiPartEmail email = new MultiPartEmail();
        email.setHostName(forwardHost);

        email.addTo(mailRecipients(to));
        email.setFrom(emailFrom);
        email.setSubject(subject);
        email.setMsg("Testing email by sahil.");

        EmailAttachment attachment = new EmailAttachment();
        attachment.setPath("c:\\sahil\\test.jpg");
        attachment.setDisposition(EmailAttachment.ATTACHMENT);
        attachment.setDescription("Picture_of_John");
        attachment.setName("John.jpg");
        email.attach(attachment);  


        MimeMultipart multiPart = getMimeMultipart(message);
        email.addPart(multiPart);

        email.send();
    }   

Если я прокомментирую ниже две строки в приведенном выше коде, он будет работать нормально.

MimeMultipart multiPart = getMimeMultipart(message);
email.addPart(multiPart);

Но с этими двумя строками я получаю исключение.

2020-04-20 15:41:44,271 ERROR com.st.ict.ols.service.impl.ReplyToMessageServiceImpl [main]  Inner Exception occurred while processing individual message. Error stacktrace is[org.apache.commons.mail.EmailException: Sending the email to the following server failed : smtpapp1.sgp.st.com:25
    at org.apache.commons.mail.Email.sendMimeMessage(Email.java:1421)
    at org.apache.commons.mail.Email.send(Email.java:1448)
    at com.st.ict.ols.service.impl.ReplyToMessageServiceImpl.sendTestMail(ReplyToMessageServiceImpl.java:342)
    at com.st.ict.ols.service.impl.ReplyToMessageServiceImpl.processMessage(ReplyToMessageServiceImpl.java:167)
    at com.st.ict.ols.service.impl.MessageServiceImpl.processMessage(MessageServiceImpl.java:22)
    at com.st.ict.ols.OlsMailSenderApplication.run(OlsMailSenderApplication.java:36)
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:732)
    at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:716)
    at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:703)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:304)
    at com.st.ict.ols.OlsMailSenderApplication.main(OlsMailSenderApplication.java:27)
Caused by: javax.mail.MessagingException: IOException while sending message;
  nested exception is:
    java.io.IOException: Exception writing Multipart
    at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1308)
    at javax.mail.Transport.send0(Transport.java:255)
    at javax.mail.Transport.send(Transport.java:124)
    at org.apache.commons.mail.Email.sendMimeMessage(Email.java:1411)
    ... 10 more
Caused by: java.io.IOException: Exception writing Multipart
    at com.sun.mail.handlers.multipart_mixed.writeTo(multipart_mixed.java:83)
    at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:884)
    at javax.activation.DataHandler.writeTo(DataHandler.java:317)
    at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1652)
    at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:961)
    at javax.mail.internet.MimeMultipart.writeTo(MimeMultipart.java:553)
    at com.sun.mail.handlers.multipart_mixed.writeTo(multipart_mixed.java:81)
    at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:884)
    at javax.activation.DataHandler.writeTo(DataHandler.java:317)
    at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1652)
    at javax.mail.internet.MimeMessage.writeTo(MimeMessage.java:1850)
    at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1259)
    ... 13 more
Caused by: javax.mail.MessagingException: Empty multipart: multipart/mixed; 
    boundary="----=_Part_1_1176580790.1587377502798"
    at javax.mail.internet.MimeMultipart.writeTo(MimeMultipart.java:548)
    at com.sun.mail.handlers.multipart_mixed.writeTo(multipart_mixed.java:81)
    ... 24 more

Код, который я написал для извлечения MimeMultipart из объекта Message JavaMailApi для установки в объекте org.apache.commons.mail.MultiPartEmail apache common с помощью функции присоединения.

    public MimeMultipart getMimeMultipart(Message message) throws Exception {
        Object content = message.getContent();
        if (content instanceof String)
            return null;        

        if (content instanceof MimeMultipart) {
            MimeMultipart multiPartResult = new MimeMultipart();
            MimeMultipart multiPart = (MimeMultipart) content;

            List<BodyPart> result = new ArrayList<>();
            for (int i = 0; i < multiPart.getCount(); i++) {
                BodyPart bodyPart = (BodyPart) multiPart.getBodyPart(i);
                result.addAll(getMimeMultipart(bodyPart));
            }
            for(BodyPart part:result) {
                multiPart.addBodyPart(part);
            }
            return multiPartResult;

        }
        return null;
    }

    private List<BodyPart> getMimeMultipart(BodyPart part) throws Exception{
        List<BodyPart> result = new ArrayList<>();
        Object content = part.getContent();

        if (content instanceof InputStream || content instanceof String) {
            if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition()) || StringUtils.isNotBlank(part.getFileName())) {
                result.add(part);
            }
            return result;
        }

        if (content instanceof MimeMultipart) {
                MimeMultipart multipart = (MimeMultipart) content;
                for (int i = 0; i < multipart.getCount(); i++) {
                    BodyPart bodyPart =  (BodyPart) multipart.getBodyPart(i);
                    result.addAll(getMimeMultipart(bodyPart));
                }
        }
        return result;
    }

Мне удалось переслать электронную почту без вложений, но возникли проблемы с пересылкой вложений/встроенных изображений.
Пожалуйста, помогите мне с этой проблемой.

Я могу переслать полное сообщение в виде вложения, как переслать сообщение как есть.

MultiPartEmail email = new MultiPartEmail();
MimeMultipart mp = new MimeMultipart();
MimeBodyPart fmbp = new MimeBodyPart();
fmbp.setContent(message, "message/rfc822");
fmbp.setDisposition(Part.INLINE);
mp.addBodyPart(fmbp);
email.setContent(mp);

или если я использую код

MimeMultipart mp = (MimeMultipart) message.getContent();
email.setContent(mp, message.getContentType());

Я получаю пересылаемое электронное письмо, подобное этому скриншот переадресованного закодированного письма


person Sahil Kumar    schedule 20.04.2020    source источник
comment
Все библиотеки Apache скрывают, что происходит на самом деле, но вы можете прочитать этот часто задаваемые вопросы по JavaMail о переадресации. сообщения.   -  person Bill Shannon    schedule 21.04.2020
comment
@BillShannon Спасибо за ссылку, теперь я могу переслать сообщение (полное сообщение с вложениями и встроенными изображениями) как вложение. Но мне нужно переслать сообщение как есть. Что мне сделать, чтобы переслать сообщение, а не как вложение?   -  person Sahil Kumar    schedule 21.04.2020
comment
Что вы имеете в виду под словом вперед? Вы действительно имеете в виду отправить повторно? Вы хотите притвориться, что это совершенно новое сообщение, и отправить его новому получателю? Просто вызовите Transport.send с сообщением и укажите новый адрес для отправки. Возможно, вам придется сначала скопировать его, используя newMsg = new MimeMessage(oldMsg);   -  person Bill Shannon    schedule 22.04.2020
comment
@BillShannon Мне нужно прочитать сообщения от одного клиента Outlook и отправить эти сообщения на другой адрес электронной почты. с помощью 'email.setContent(readMessage, message/rfc822);' Я могу как-то добиться этого. Когда я отправляю прочитанную почту в Gmail, она выглядит идеально, но когда я отправляю прочитанную почту в Outlook. я получаю это как вложение.   -  person Sahil Kumar    schedule 22.04.2020
comment
@BillShannon проверить изображение Электронное письмо, которое я отправил на другой идентификатор Outlook, выглядит так. Но для Gmail работает нормально.   -  person Sahil Kumar    schedule 22.04.2020
comment
Правильно, если вам просто нужно отправить его повторно, сделайте копию сообщения и используйте эту копию с помощью Transport.send и с указанным новым адресом.   -  person Bill Shannon    schedule 23.04.2020
comment
@BillShannon Смогла этого добиться, спасибо! Возможно, проблема была из-за общего API Apache, теперь я напрямую использовал API почты Java.   -  person Sahil Kumar    schedule 23.04.2020


Ответы (1)


Здесь ситуация читает почту с одного почтового сервера и отправляет одно и то же сообщение на другой адрес электронной почты в том же приложении.

Для этого я использовал Java Mail API как для чтения, так и для отправки. Обязательно обновите свойства, если вы используете другой хост для обоих шагов.

    private void sendMailJavax(Message oldMessage) {
        try { 
            // creating a new message using the older message
            MimeMessage message = new MimeMessage((MimeMessage)oldMessage);
            // updating properties as per sender Mailing API
            message.getSession().getProperties().clear();
            message.getSession().getProperties().setProperty("mail.smtp.host", forwardHost);

            // setting appropriate headers. // make sure you don't append using .add methods.
            message.setFrom(new InternetAddress(emailFrom));
            message.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
            message.setReplyTo(new Address[] { new InternetAddress(replyToEmail)});

            Transport.send(message); 
            System.out.println("Email Sent  successfully...."); 
            } catch (MessagingException mex) { 
                mex.printStackTrace(); 
            } 
    }
person Sahil Kumar    schedule 23.04.2020