views:

4544

answers:

5

I want to create a Java File object in memory (without creating a physical file) and populate its content with a byte array.

Can this be done?

The idea is to pass it to a Spring InputStreamSource. I'm trying the method below, but it returns saying "the byte array does not contain a file name.".

MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message);   
helper.setFrom("[email protected]", "xyz");
helper.setTo(email);
helper.setText(body,true);
helper.setSubject(subject);
helper.addInline("cImage",
        new InputStreamResource(new ByteArrayInputStream(imageByteArr)));

mailSender.send(message);
+4  A: 

Maybe you need to use the other constructor of InputStreamResource?

starblue
Nope. I get - java.lang.IllegalStateException: abc.png does not carry a filename at org.springframework.core.io.AbstractResource.getFilename(AbstractResource.java:148) at org.springframework.mail.javamail.MimeMessageHelper.addInline(MimeMessageHelper.java:922)
+3  A: 

Can you paste the full stack trace? There is no such thing as an "in memory" file. Using a ByteArrayInputStream should be sufficient.


You need to implement Resource#getFilename(). Try the following:

helper.addInline("cImage", new ByteArrayResource(imageByteArr){
            @Override
            public String getFilename() {
                return fileName;
            }
        });
Kevin
java.lang.IllegalStateException: resource loaded from byte array does not carry a filename at org.springframework.core.io.AbstractResource.getFilename(AbstractResource.java:148) at org.springframework.mail.javamail.MimeMessageHelper.addInline(MimeMessageHelper.java:922)
Thanks Kevin, it worked!! Fantastic solution.
You can hopefully see it in action soon at www.creately.com :) (We are in private beta atm.)
also works perfectly with 'addAttachment'
ninesided
A: 

Have you tried changing the resource you feed to addInline()? If you wanted the resource to be in memory, I would have tried a org.springframework.core.io.ByteArrayResource.

Update: I think you might need to use the DataSource version of the addInline() method and then use a byte array bound data source object to feed the data into the helper class. I would try the following:

MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message);              
helper.setFrom("[email protected]", "xyz");
helper.setTo(email);
helper.setText(body,true);
helper.setSubject(subject);

// use javax.mail.util.ByteArrayDataSource
ByteArrayDataSource imgDS = new ByteArrayDataSource( imageByteArr, "image/png");
helper.addInline("cImage", imgDS);

mailSender.send(message);
Dan
Tried it. Same exception :( What I get is a raw array of bitmap data. Looks like I need to put it into a file before anything?
You might need to use the version of addInLine() that accepts a DataSource as your second parameter. There is a javax.util.mail.ByteArrayDataSource that implements the functionality of wrapping a byte array without a physical file.
Dan
A: 

Maybe its worth trying a different overload of the method:

addInline(String contentId, 
          InputStreamSource inputStreamSource, 
          String contentType)

I.e.:

addInline("cImage", 
          new InputStreamSource () 
          {  
             final private InputStream src = 
                                     new ByteArrayInputStream(imageByteArr);
             public InputStream getInputStream() {return src;}
          },
          "image/jpeg"); // or whatever image type you use
Totophil
A: 

It is important to create the MimeMessageHelper object correctly to support attachments and inline resources.

Example: MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");

In this example since multipart is set to true MULTIPART_MODE_MIXED_RELATED will be used and attachments and inline resouces will be supported.