1

Im trying to download all new e-mails attachments from my email with javamail and through imap. It all works fine, how ever some attachments are in pdfs and decoded as BASE64, which my statement

if (msg.getContent() instanceof Multipart) 

dont catch, since its com.sun.mail.util.BASE64DecoderStream@33c7e1bb.

How do I get this attachment and download it to my hard drive?

Tried this so far, and the first IF statement catches the attachments with Base64 decoding.

for (Message msg : messages) {
        Address[] fromAddress = msg.getFrom();
        String from = fromAddress[0].toString();
        String subject = msg.getSubject();
        String sentDate = msg.getSentDate().toString();

        String messageContent = "";
        String attachFiles = "";

        System.out.println(msg.getContent());


        if (msg.getContent() instanceof BASE64DecoderStream)
        {
            BASE64DecoderStream base64DecoderStream = (BASE64DecoderStream) msg.getContent();
            byte[] byteArray = IOUtils.toByteArray(base64DecoderStream);
        }
        if (msg.getContent() instanceof Multipart) {


            Multipart multipart = (Multipart) msg.getContent();

            for (int i = 0; i < multipart.getCount(); i++) {
                Part part = multipart.getBodyPart(i);
                String disposition = part.getDisposition();

                if ((disposition != null) &&
                        ((disposition.equalsIgnoreCase(Part.ATTACHMENT) ||
                                (disposition.equalsIgnoreCase(Part.INLINE))))) {
                    MimeBodyPart mimeBodyPart = (MimeBodyPart) part;
                    String fileName = mimeBodyPart.getFileName();
                    attachFiles += fileName;
                    File fileToSave = new File(fileName);
                    mimeBodyPart.saveFile(saveDirectory + File.separator + fileToSave);
                    System.out.println("saved attachment: " + fileName + " to disk at: " + saveDirectory);
                }
            }
        }
        System.out.println("\t From: " + from);
        System.out.println("\t Subject: " + subject);
        System.out.println("\t Sent Date: " + sentDate);
        System.out.println("\t Attachments: " + attachFiles);
        System.out.println("");
    }
}

Can also use NodeJS if there is a simple and easy way to download attachments to my disk. Tried node-imap but I got the same error there.

JesperN
  • 77
  • 1
  • 4
  • Possible duplicate of [Easy way to write contents of a Java InputStream to an OutputStream](https://stackoverflow.com/questions/43157/easy-way-to-write-contents-of-a-java-inputstream-to-an-outputstream) – jmehrens Sep 26 '17 at 14:48

1 Answers1

1

You don't need to handle base64 as a special case. The saveFile method that you're already using will decode the content and save it. Just remove your first "if" statement.

And you don't want to use instanceof to check for multipart since it can be very expensive if it's not a multipart. Instead, use if (msg.isMimeType("multipart/*")).

Note also that your multipart loop will only handle the simplest messages. It will fail with messages that contain multiparts nested in multiparts. typically this would only be signed or encrypted messages, which you might not want to handle. And it will fail with "attachments" that don't have the expected Content-Disposition header or that don't specify a file name. (Hopefully this is rare these days, but some people still use old or broken mailers.)

Finally, you should never use the file name included in a mail message "as is". That name should never be trusted. It might be used to overwrite files on your disk.

Bill Shannon
  • 29,579
  • 6
  • 38
  • 40