How can I send JsonNode as an email attachment - java

How can I send JsonNode as an email attachment in java.email as a json file
// Json node bit
JsonNode requestBody = request().body().asJson();
// Mail bit
messageBodyPart = new MimeBodyPart();
messageBodyPart.setDataHandler(new DataHandler( It should be passed here));
messageBodyPart.setFileName("file.json");
multipart.addBodyPart(messageBodyPart);

If you look at the DataHandler docs, it shows three constructors. One of them takes a DataSource. The javamail API has an implementation called ByteArrayDataSource
So, if you figure out how to serialize the JsonNode to a JSON String, you can do this:
String jsonStr = ...
new DataHandler(new ByteArrayDataSource(jsonStr.getBytes()));
Also, keep in mind that you should also set the MIME type of the attachment to applicatio/json.

Related

How can I write a more complex body of a mail with Multipart in Java?

I am trying to send an email in Java. What I am doing now is described in the following:
my_result = my_function();
// header
String notificationSubject = "Test email";
// content
final MimeMultipart notificationContent = new MimeMultipart();
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setText("Plain text.");
notificationContent.addBodyPart(messageBodyPart);
... code to send the email ...
At the moment, the body of the email should be composed only by the text: "Plain text". I would like to write a more complex email like the following one:
Dear all,
the result of the operation was not successful. The following value caused a problem:
Value: my_result
Best regards.
Where my_result is the content of the corresponding variable.
How can I achieve the email I want managing the returns, the blank lines and the variable?

Control what DataContentHandler to use for a MimeMessage attachment?

I am creating an attachment to MimeMessage for a Tiff image with a byte array.
ByteArrayOutputStream out = new ByteArrayOutputStream();
MimeBodyPart body = new MimeBodyPart();
body.setContent(tiffByteArray, "image/tiff");
body.setDisposition("attachment");
body.setFileName(filename);
MimeMultipart multipart = new MimeMultipart();
multipart.addBodyPart(body);
MimeMessage message = new MimeMessage(Session.getDefaultInstance(System.getProperties()));
message.setContent(multipart);
message.writeTo(out);
String mimeContent = out.toString();
This normally works. The image is converted to a base64 string in the message. However, at some point something on the system occurs and this piece of code starts using com.sun.xml.internal.messaging.saaj.soap.ImageDataContentHandler. This particular converted expects an java.awt.Image object as opposed to a byte array (relevant source). I get the following error:
Unable to encode the image to a stream ImageDataContentHandler requires Image object, was given object of type class [B
I can see that you can set the javax.activation.DataHandler on the javax.mail.internet.MimeMessage and in the DataHandler you can set the javax.activation.DataContentHandlerFactory, but I'm not sure what to set it to.
Is there a way to force a byte array to be converted to a base64 encoded String regardless of the mime type?
javax.mail provides a DataSource implementation for bytes that you can explicitly use.
ByteArrayDataSource dataSource = new ByteArrayDataSource(tiffByteArray, "image/tiff");
DataHandler byteDataHandler = new DataHandler(dataSource);
body.setDataHandler(byteDataHandler);
body.setDisposition("attachment");
body.setFileName(filename);

html email with reference to an image as base64 String

I would like to send an email with the Java Mail API (javax.mail). The message must contain html and inside there is a reference to an image. There is a challenge, because no reference to a physical file on disk is allowed but instead I have created a base64 string (http://www.base64-image.de/step-1.php) for that image and copied that data to a static String variable.
With javax.mail I build a message of type MulitPart with two parts. The first part is the html itself and the second part is the image. The html part reference to the image via <img src="cid:image-id"/>.
Message msg = new MimeMessage(session);
Multipart multipart = new MimeMultipart("related");
BodyPart htmlPart = new MimeBodyPart();
htmlPart.setContent("<html><body><h2>A title</h2>Some text in here<br/>" +
"<img src=\"cid:the-img-1\"/><br/> some more text<img src=\"cid:the-img-1\"/></body></html>", "text/html");
multipart.addBodyPart(htmlPart);
public static final String base64logo = "/9j/4AAQSkZJRgABAQEASABIAAD/4QBe…"; // ein ganz langer String erzeugt über http://www.base64-image.de/step-1.php
sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
byte[] imageByte = decoder.decodeBuffer(base64logo);
InternetHeaders header = new InternetHeaders();
BodyPart imgPart=new MimeBodyPart(header, imageByte);
imgPart.setHeader("Content-ID","the-img-1");
imgPart.setDisposition(MimeBodyPart.INLINE);
multipart.addBodyPart(imgPart);
msg.setContent(multipart);
Unfortunately the image is missing in the incoming email.
When I point to the file on my disk it is working:
DataSource ds=new FileDataSource("c:/temp/image001.jpg");
imgPart.setDataHandler(new DataHandler(ds));
We are developing with Talend and we cannot reference
to external files because that would make the deployment process
more complicate.
Can you find some wrong doings in my approach?
Kind regards
Hilderich
Try putting angle braces here
imgPart.setHeader("Content-ID","<the-img-1>");
I found this answer on the comments of an old post from this blog
http://www.jroller.com/eyallupu/entry/javamail_sending_embedded_image_in
In the comment of Aravind Velayudhan Nair
It worked for me!
This has been asked before a long time ago. But I will answer this as I have faced the same issue, from my own answer here.
byte[] tile = DatatypeConverter.parseBase64Binary(base64logo);
BodyPart messageBodyPart = new MimeBodyPart();
DataHandler dataHandler = new DataHandler(new ByteArrayDataSource(tile, "image/jpeg"));
messageBodyPart.setDataHandler(dataHandler);
messageBodyPart.setHeader("Content-ID", "<the-img-1>");
multipart.addBodyPart(messageBodyPart);
msg.setContent(multipart);
Hope it will help someone.

Java Mail - Attachments not showing in email clients?

Ok so I'm having to alter some old code from another dev that he sent up for sending emails from our app with Java Mail. This has worked fine for a long time but now we are required to send pdf attachments as well.
So basically below, assume there is an object "mail" that has getters for the text and html messages as well as now a getter for the pdf filename to load from the filesystem and attach to the mail.
I've altered the below code where marked, so if there is a pdf to attach, load from filesystem and attach. I've tried to use the same structure as the previous code, although I suspect its not all required?
Multipart mp = new MimeMultipart("alternative");
// Create a "text" Multipart message
BodyPart textPart = new MimeBodyPart();
textPart.setContent(mail.getText(), "text/plain");
mp.addBodyPart(textPart);
// Create a "HTML" Multipart message
Multipart htmlContent = new MimeMultipart("related");
BodyPart htmlPage = new MimeBodyPart();
htmlPage.setContent(mail.getHtml(), "text/html; charset=UTF-8");
htmlContent.addBodyPart(htmlPage);
BodyPart htmlPart = new MimeBodyPart();
htmlPart.setContent(htmlContent);
mp.addBodyPart(htmlPart);
// NEW CODE STARTS HERE
if(StringUtils.isNotBlank(mail.getPdfAttachmentFileName())) {
Multipart pdfContent = new MimeMultipart("mixed"); //<---- this appears to be an issue???
BodyPart pdfPage = new MimeBodyPart();
File file = new File(uploadDir + "/" + mail.getPdfAttachmentFileName());
DataSource dataSource = new ByteArrayDataSource(new FileInputStream(file), "application/pdf");
pdfPage.setDataHandler(new DataHandler(dataSource));
pdfPage.setFileName(mail.getPdfAttachmentFileName());
pdfContent.addBodyPart(pdfPage);
BodyPart pdfPart = new MimeBodyPart();
pdfPart.setContent(pdfContent);
mp.addBodyPart(pdfPart);
}
// NEW CODE ENDS HERE
mimeMessage.setContent(mp);
At any rate, the above works, sort of. There are no errors or exceptions and the message gets sent. BUT the attachment doesn't appear depending on which email client you recieve the mail with.
With the code as above, Outlook receives the message as readable and the attachment is visible and downloadable. This is perfect. BUT in GMail, the message is still readable, the paperclip appears to indicate there is an attachment, but there is no attachment to download?
If you switch the `Multipart pdfContent = new MimeMultipart("mixed");' to be "related" rather than "mixed" the exact opposite is true. GMail receives it perfectly but Outlook only gets the message and paperclip, no actual attachment.
Obviously we need to be sending emails to our customers with no knowledge of their email client used to open them! Obviously I'm a novice at Java Mail so have simply copied suggested code but this isn't gelling well with our existing code!
Any ideas how to alter the above to make it completely email client independant?
Ok turns out Spring has a helper class to hide all this mess away from you.
I've refactored all of the above code into the following and it works great;
MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true, "UTF-8");
message.setTo(mail.getTo());
message.setFrom(mail.getFrom());
message.setSubject(mail.getSubject());
message.setText(mail.getText(), mail.getHtml());
if(StringUtils.isNotBlank(mail.getPdfAttachmentFileName())) {
File file = new File(uploadDir + "/" + mail.getPdfAttachmentFileName());
DataSource dataSource = new ByteArrayDataSource(new FileInputStream(file), "application/pdf");
message.addAttachment(mail.getPdfAttachmentFileName(), dataSource);
}

How do I send mail with both plain text as well as HTML text so that each mail reader can choose the format appropriate for it?

From http://www.oracle.com/technetwork/java/faq-135477.html#sendmpa:
You'll want to send a MIME multipart/alternative message. You
construct such a message essentially the same way you construct a
multipart/mixed message, using a MimeMultipart object constructed
using new MimeMultipart("alternative"). You then insert the text/plain
body part as the first part in the multpart and insert the text/html
body part as the second part in the multipart. You'll need to
construct the plain and html parts yourself to have appropriate
content. See RFC2046 for details of the structure of such a message.
Can someone show me some sample code for this?
This is a part of my own code:
final Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(senderAddress, senderDisplayName));
msg.addRecipient(Message.RecipientType.TO,
new InternetAddress(m.getRecipient(), m.getRecipientDisplayName()));
msg.setSubject(m.getSubject());
// Unformatted text version
final MimeBodyPart textPart = new MimeBodyPart();
textPart.setContent(m.getText(), "text/plain");
// HTML version
final MimeBodyPart htmlPart = new MimeBodyPart();
htmlPart.setContent(m.getHtml(), "text/html");
// Create the Multipart. Add BodyParts to it.
final Multipart mp = new MimeMultipart("alternative");
mp.addBodyPart(textPart);
mp.addBodyPart(htmlPart);
// Set Multipart as the message's content
msg.setContent(mp);
LOGGER.log(Level.FINEST, "Sending email {0}", m);
Transport.send(msg);
Where m is an instance of my own class.

Categories