1

I am using the apache commons fileupload for uploading the file. I want to attach this file to an email. I don't want to write to temp file but I want to keep the data in memory and send it as an attachment. I need direction from here. Thanks in advance

DiskFileItemFactory factory = new DiskFileItemFactory();
                PortletFileUpload upload = new PortletFileUpload(factory);
                List items = upload.parseRequest(request);

                Iterator iter = items.iterator();

                while(iter.hasNext()) {
                    FileItem item = (FileItem) iter.next();
                    if(item.isFormField()) {

                        String name = item.getFieldName();
                        String value = item.getString();
                        response.setRenderParameter(name, value);

                    } else {

                        String fieldName = item.getFieldName();
                        String fileName = item.getName();
                        //String contentType = item.getContentType();
                        boolean isInMemory = item.isInMemory();
                        long sizeInBytes = item.getSize();

                        InputStream uploadedStream = item.getInputStream();

                    }
                }

UPDATE I have the following method signature for sending an email with attachement and its working fine.

sendWithFileAttachment (String[] recipients,
            String subject,
            File message,
            String from,
            String filename) {

            BodyPart messageBodyPart = new MimeBodyPart();

    // Fill the message
    messageBodyPart.setText("Pardon Ideas");

    Multipart multipart = new MimeMultipart();
    multipart.addBodyPart(messageBodyPart);

    // Part two is attachment
    messageBodyPart = new MimeBodyPart();
    DataSource source = new FileDataSource(message);
    messageBodyPart.setDataHandler(new DataHandler(source));
    messageBodyPart.setFileName(filename);
    multipart.addBodyPart(messageBodyPart);

    // Put parts in message

    msg.setContent(multipart);

    Transport.send(msg);

}

UPDATE 2: I am getting the below error after implementing your code. Can you please help me with this

HIT ME! 15782
Jul 31, 2012 11:17:56 AM test.test.EmailUtility1$InputStreamMimeBodyPart getContentStream
SEVERE: null
Throwable occurred: java.io.IOException: Stream closed
    at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:156)
    at java.io.BufferedInputStream.reset(BufferedInputStream.java:425)
    at test.test.EmailUtility1$InputStreamMimeBodyPart.getContentStream(EmailUtility1.java:174)
    at javax.mail.internet.MimePartDataSource.getInputStream(MimePartDataSource.java:94)
    at javax.activation.DataHandler.writeTo(DataHandler.java:302)
    at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1350)
    at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:845)
    at javax.mail.internet.MimeMultipart.writeTo(MimeMultipart.java:361)
    at com.sun.mail.handlers.multipart_mixed.writeTo(multipart_mixed.java:85)
    at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:881)
    at javax.activation.DataHandler.writeTo(DataHandler.java:314)
    at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1350)
    at javax.mail.internet.MimeMessage.writeTo(MimeMessage.java:1683)
    at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:585)
    at javax.mail.Transport.send0(Transport.java:169)
    at javax.mail.Transport.send(Transport.java:98)
    at test.test.EmailUtility1.sendWithFileAttachment(EmailUtility1.java:155)
    at test.test.TestEmail.main(TestEmail.java:32)
Exception in thread "main" javax.mail.MessagingException: IOException while sending message;
  nested exception is:
    java.io.IOException: Stream closed
    at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:625)
    at javax.mail.Transport.send0(Transport.java:169)
    at javax.mail.Transport.send(Transport.java:98)
    at test.test.EmailUtility1.sendWithFileAttachment(EmailUtility1.java:155)
    at test.test.TestEmail.main(TestEmail.java:32)
Caused by: java.io.IOException: Stream closed
    at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:156)
    at java.io.BufferedInputStream.read(BufferedInputStream.java:319)
    at java.io.FilterInputStream.read(FilterInputStream.java:101)
user525146
  • 3,918
  • 14
  • 60
  • 103

1 Answers1

1

You need to override MimeBodyPart (which you are most likely using, I assume) to be able to get their content through a Stream.

public void sendWithFileAttachment(String recipient,
                String subject,
                InputStream message,
                String from,
                String filename) throws MessagingException {
    MimeMessage msg = new MimeMessage(getSession());

    // set the from and to address
    InternetAddress addressFrom = new InternetAddress(from);
    msg.setFrom(addressFrom);

    InternetAddress addressTo = new InternetAddress(recipient);
    msg.setRecipient(Message.RecipientType.TO, addressTo);

    BodyPart messageBodyPart = new MimeBodyPart();

    // Fill the message
    messageBodyPart.setText("Pardon Ideas");

    Multipart multipart = new MimeMultipart();
    multipart.addBodyPart(messageBodyPart);

    // Part two is attachment
    messageBodyPart = new InputStreamMimeBodyPart(message);
    messageBodyPart.setFileName(filename);
    multipart.addBodyPart(messageBodyPart);

    // Put parts in message

    msg.setContent(multipart);

    Transport.send(msg);
    // important: you need to close the message stream manually
    try {
        message.close();
    } catch (IOException ex) {
        // meh. So what.
    }

}

private class InputStreamMimeBodyPart extends MimeBodyPart {

private InputStream inputStream;

    public InputStreamMimeBodyPart(InputStream source) {
        this.inputStream = source;
        if(!inputStream.markSupported()) {
            throw new IllegalArgumentException("only streams with mark supported are ok");
        }
        inputStream.mark(Integer.MAX_VALUE); // remeber the whole stream.
    }

    @Override
    protected InputStream getContentStream() throws MessagingException {
        throw new IllegalStateException("getContentStream is not implemented on purpose.");
    }

    @Override
    public void writeTo(OutputStream os) throws IOException, MessagingException {
        System.out.println("writing to somewhere.");
        byte[] buf = new byte[32];
        int length;
        inputStream.reset();
        while((length = inputStream.read(buf)) > -1 ) {
            os.write(buf, 0, length);
        }
    }
}

private Session getSession() {
    // here you do authentication etc.
    Properties properties = new Properties();
    return Session.getInstance(properties);
}
Angelo Fuchs
  • 9,825
  • 1
  • 35
  • 72
  • Can you please help me with this ? – user525146 Jul 31 '12 at 05:51
  • @user525146 There you go. You left out some parts of your method in your question so you will have to adapt. Be aware (this is critical) that your InputStreams MUST support the mark functions. This is because in this implementation (on my machine) the mail api calls 'getContentStream' twice. I haven't figured out yet why it does that, but as long as there is no reason to do so, I won't bother. – Angelo Fuchs Jul 31 '12 at 12:33
  • I am getting error when I executed your code. Please see the update 2 – user525146 Jul 31 '12 at 16:24
  • @user525146 So, I fixed it. The changes are from transport.send downwards (including the closing of the stream) – Angelo Fuchs Jul 31 '12 at 19:35
  • I am getting all junk characters in the body of email and it is not a file attachment. The attached file is an excel file and I don't see that attached to the email. – user525146 Aug 01 '12 at 15:20
  • @user525146 I won't have time to look into this for some days. But I'll keep it open, so I will look at it Monday Evening (I'm UTC+2), if I haven't answered until then, drop me a line. – Angelo Fuchs Aug 02 '12 at 14:54
  • can you help me on this if you have some time on it. thanks ! – user525146 Aug 07 '12 at 14:19
  • @user525146 Sorry, looks bad mate. I'm pretty busy and that will stay so for at least two weeks. Good luck. – Angelo Fuchs Aug 07 '12 at 14:56