downloading email body containing inline images in java

email, inline-images, java

Solution

I wrote below code to convert email body text to pdf including inline images. in code i replaced the image code(ex: cid:image001.jpg@01D17AAA.1EA2A6A0) with download image path. I am constructing the "hashmap" for image key and download path while downloading the image.

 HTMLWorker htmlWorker = new HTMLWorker(document);
            if(bodyStr!=null)
            {

                //find inline images
                inlineImages=downloadInLineImage(mostRecentMatch, dynamicOutputDirectory);
                if(inlineImages!=null)
                {

                    for (Map.Entry<String, String> entry : inlineImages.entrySet()) {
                        //System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
                        bodyStr=bodyStr.replaceAll("cid:"+entry.getKey() , entry.getValue());
                    }
                }
                htmlWorker.parse(new StringReader(bodyStr));

        }

Download Inline image with passing Item.

 private HashMap<String,String> downloadInLineImage(Item item, String dynamicOutputDirectory)
        throws Exception, ServiceLocalException {
    //create output directory if not present

        //bind the item to a new email message. if you do not bind, then the getHasAttachments() function will fail
    EmailMessage mostRecentMatch = (EmailMessage)item;
    String from = mostRecentMatch.getFrom().getAddress();
    String user =StringUtils.substringBefore(from, "@");
    AttachmentCollection collection=item.getAttachments();

    HashMap<String,String> inlineFiles=new HashMap<String,String>();

    if(collection.getCount()>0)
    {
        for (Attachment attachment : collection.getItems()) {

            if(attachment.getIsInline())
            {

                FileAttachment currentFile = (FileAttachment) attachment;
                String filePath=dynamicOutputDirectory+"/"+user+currentFile.getName();
                File file=new File(filePath);
                FileOutputStream fio=new FileOutputStream(file);
                currentFile.load(fio);
                inlineFiles.put(currentFile.getContentId(), filePath);
                fio.close();
            }
        }
    }

Problem

My issue goes as follows: I have My code setup to read emails from a particular account. That part works perfectly. the issue is with parsing the Email message. Separating attachments and email body(containing inline images). My code goes like this: ``` Void readMessages(Folder folder){ Message[] messages = folder.getMessages(); // loading of message objects. for (int messageNumber = 0; messageNumber < messages.length; messageNumber++) { final Message currentMessage = messages[messageNumber]; logger.info("Handling the mail with subject " + currentMessage.getSubject()); logger.info("Content type for the current message is " + currentMessage.getContentType()); final String messageFileName = currentMessage.getFileName(); logger.info("File name for the message " + messageFileName + ". File name is blank " + StringUtils.isBlank(messageFileName)); Object messageContentObject = currentMessage.getContent(); if (messageContentObject instanceof Multipart) { Multipart multipart = (Multipart) messageContentObject; // downloading all attachments.... int attachmentCount = multipart.getCount(); logger.info("Number of attachments "); for (int i = 0; i < attachmentCount; i++) { Part part = (Part) multipart.getBodyPart(i); downloadAttachment(part, folderPath.toString()); } } } } } private void downloadAttachment(Part part, String folderPath) throws Exception { String disPosition = part.getDisposition(); String fileName = part.getFileName(); String decodedText = null; logger.info("Disposition type :: " + disPosition); logger.info("Attached File Name :: " + fileName); if (disPosition != null && disPosition.equalsIgnoreCase(Part.ATTACHMENT)) { logger.info("DisPosition is ATTACHMENT type."); File file = new File(folderPath + File.separator + decodedText); file.getParentFile().mkdirs(); saveEmailAttachment(file, part); } else if (fileName != null && disPosition == null) { logger.info("DisPosition is Null type but file name is valid. Possibly inline attchment"); File file = new File(folderPath + File.separator + decodedText); file.getParentFile().mkdirs(); saveEmailAttachment(file, part); } else if (fileName == null && disPosition == null) { logger.info("DisPosition is Null type but file name is null. It is email body."); File file = new File(folderPath + File.separator + "mail.html"); file.getParentFile().mkdirs(); saveEmailAttachment(file, part); } } protected int saveEmailAttachment(File saveFile, Part part) throws Exception { BufferedOutputStream bos = null; InputStream is = null; int ret = 0, count = 0; try { bos = new BufferedOutputStream(new FileOutputStream(saveFile)); part.writeTo(new FileOutputStream(saveFile)); } finally { try { if (bos != null) { bos.close(); } if (is != null) { is.close(); } } catch (IOException ioe) { logger.error("Error while closing the stream.", ioe); } } return count; } ``` The problem i get is when i run this code, i get an HTML file but the inline images is replaced by a sign for error image which indicates the image with no source. Please help me out with. Let me know if any more info is required. I also tried saving the body as an `.eml` file by changing: ``` File file = new File(folderPath + File.separator + "mail.html"); ``` to ``` File file = new File(folderPath + File.separator + "mail.eml"); ``` BUt i got the same results.

Original source