2

I'm trying to read in emails, save the email as an object, save their attachments and then POST the object as JSON to an API. Everything works fine except that the body only outputs as com.sun.mail.util.BASE64DecoderStream@1q9q9qj4. I thought the code would handle the message body with attachments but it doesn't seem to work.

public class ReadEmails {
    private static String saveDirectory = "C://attachments"; 

    public void setSaveDirectory(String dir) {
        ReadEmails.saveDirectory = dir;
    }

    public static void downloadEmailAttachments(String host, String port, String userName, String password) {
        Properties properties = new Properties();

        properties.put("mail.pop3.host", host);
        properties.put("mail.pop3.port", port);
        properties.put("mail.pop3.starttls.enable", "true");
        properties.put("mail.pop3.ssl.trust", host);
        properties.setProperty("mail.pop3.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        properties.setProperty("mail.pop3.socketFactory.fallback", "true");
        properties.setProperty("mail.pop3.socketFactory.port", String.valueOf(port));

        Session session = Session.getDefaultInstance(properties);

        try {
            Store store = session.getStore("pop3");
            store.connect(userName, password);

            Folder folderInbox = store.getFolder("INBOX");
            folderInbox.open(Folder.READ_ONLY);

            Message[] arrayMessages = folderInbox.getMessages();

            for (int i = 0; i < arrayMessages.length; i++) {
                Message message = arrayMessages[i];
                Address[] fromAddress = message.getFrom();
                String from = fromAddress[0].toString();
                String subject = message.getSubject();
                String sentDate = message.getSentDate().toString();

                String contentType = message.getContentType();
                String messageContent = "";

                String attachFiles = "";

                if (contentType.contains("multipart")) {
                    // content may contain attachments
                    Multipart multiPart = (Multipart) message.getContent();
                    int numberOfParts = multiPart.getCount();
                    for (int partCount = 0; partCount < numberOfParts; partCount++) {
                        MimeBodyPart part = (MimeBodyPart) multiPart.getBodyPart(partCount);
                        if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition())) {
                            // this part is attachment
                            String fileName = part.getFileName();
                            attachFiles += fileName + ", ";
                            part.saveFile(saveDirectory + File.separator + fileName);
                        } else {
                            // this part may be the message content
                            messageContent = part.getContent().toString();
                        }
                    }

                    if (attachFiles.length() > 1) {
                        attachFiles = attachFiles.substring(0, attachFiles.length() - 2);
                    }
                } else if (contentType.contains("text/plain") || contentType.contains("text/html")) {
                    Object content = message.getContent();
                    if (content != null) {
                        messageContent = content.toString();
                    }
                }


                NewCase nc = new NewCase();
                nc.setTitle(subject);
                nc.setDescription(messageContent);
                nc.setEmail(from);

                sendEmails(nc);
                System.out.print("email: "+ nc.getTitle() + nc.getDescription() + nc.getEmail());
            }

            folderInbox.close(false);
            store.close();
        } catch (NoSuchProviderException ex) {
            System.out.println("No provider for pop3.");
            ex.printStackTrace();
            System.out.println(ex);;
        } catch (MessagingException ex) {
            System.out.println("Could not connect to the message store");
            ex.printStackTrace();
            System.out.println(ex);;
        } catch (IOException ex) {
            ex.printStackTrace();
            System.out.println(ex);;
        }
    }
    static void sendEmails(NewCase nc) {
        final String url = "http://localhost:8080/email";

        String title = nc.getTitle();
        String description = nc.getDescription();
        String email = nc.getEmail();

        HttpClient httpClient = HttpClientBuilder.create().build();     
            HttpPost p = new HttpPost(url);        

            p.setEntity(new StringEntity("{\"title\":\"" + title + "\",\"description\":\"" + description + "\",\"email\":\""+ email +"\"}", 
                             ContentType.create("application/json")));

            try {
                HttpResponse r = httpClient.execute(p);
                System.out.println(r.getStatusLine().getStatusCode());

            } catch (ClientProtocolException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
}
Niall
  • 497
  • 1
  • 6
  • 16
  • Your question is unclear. `the body only outputs as com.sun.mail.util.BASE64DecoderStream@1q9q9qj4` outputs where? – Nikolai Shevchenko Jun 14 '18 at 15:42
  • I'm sorry if it's unclear, when I POST the NewCase object to the API it gets entered into a database. In here it the field that holds the message contains com.sun.mail.util.BASE64DecoderStream@1q9q9qj4 instead of the actual message. The API and database work fine for other things so I'm thinking maybe a problem occurs when converting the NewCase object to JSON – Niall Jun 14 '18 at 16:27
  • 1
    i got it. The problem is when converting `part.getContent()` to string, because here `part.getContent()` is instance of `BASE64DecoderStream` (which is inherited from `InputStream`) and its `toString()` method doesn't consume the stream into string. You need to perform conversion manually (see https://stackoverflow.com/questions/309424/read-convert-an-inputstream-to-a-string for details) – Nikolai Shevchenko Jun 14 '18 at 17:59
  • Thanks, whats the best way of converting it? I've tried a few different methods such as using part.getInputStream() and then using Base64.getDecoder() but nothing seems to work. – Niall Jun 15 '18 at 08:38
  • 1
    I personally use `IOUtils.toString(bodyPart.getInputStream(), Charset.forName("UTF-8"));` in my project. IOUtils -> https://mvnrepository.com/artifact/commons-io/commons-io/2.6 – Nikolai Shevchenko Jun 15 '18 at 09:08
  • Assuming the part is really a text part (`part.isMimeType("text/*")`), part.getContent() should return a String. If that's not working, something else is wrong, possibly a class loader problem. Where is your application running? – Bill Shannon Jun 15 '18 at 19:03
  • Also, you should [get rid of the socket factory properties](https://javaee.github.io/javamail/FAQ#commonmistakes), you don't need them. And you might want to read [this JavaMail FAQ entry about finding the main message body](https://javaee.github.io/javamail/FAQ#mainbody). Finally, I hope NewCase is ensuring that the message body is properly escaped if it contains double quotes. – Bill Shannon Jun 15 '18 at 19:06

0 Answers0