In my java application, I want to send an e-mail using the MimeMessageHelper:
My file name is: âTestFileüa.PNG
my code is here:
SimpleMailMessage mail= new SimpleMailMessage(templateMessage);
mail.setTo(personMail);
mail.setSubject(subject);
mail.setText(content);
MimeMessage message = mailSender.createMimeMessage();
try {
MimeMessageHelper messageHelper = new MimeMessageHelper(message,true);
messageHelper.setFrom(mail.getFrom());
messageHelper.setTo(mail.getTo());
messageHelper.setSubject(mail.getSubject());
messageHelper.setText(mail.getText());
messageHelper.addAttachment(fileName, new ByteArrayResource(attchmentFile));
} catch (MessagingException e) {
e.printStackTrace();
}
The file is correcttly sent, but in outlook, the special characters of my file aren't correctly displayed.
It looks like there is a problem with the encoding of the filename. I would try setting an appropriate character encoding when creating the mime helper object. For example:
MimeMessageHelper messageHelper =
new MimeMessageHelper(message, true, "UTF-8");
before this line,
messageHelper.addAttachment(fileName, new ByteArrayResource(attchmentFile));
I added :
fileName = MimeUtility.encodeText(filename);
and this work perfectly!
Related
I'd like to add an inline bitmap (generated within the code) to an email to be sent via JavaMail in Android. Below is my code currently:
try {
// Compose the message
// javax.mail.internet.MimeMessage class is
// mostly used for abstraction.
Message message = new MimeMessage(session);
// header field of the header.
message.setFrom(new InternetAddress("service#someone.com"));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipient));
message.setSubject("Workside Verification Service");
message.setText(
"Thank you for registering. Please click on the following link to activate your account:\n\n"
+ urlWithToken
+ "\n\nRegards,\nThe Workside Team");
// Add the generated QR code bitmap here
Multipart multipart = new MimeMultipart("related");
MimeBodyPart imgPart = new MimeBodyPart();
// imageFile is the file containing the image
// TODO - pass bitmap to imageFile below
File file = new File(null);
OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
mBitmapQR.compress(Bitmap.CompressFormat.PNG, 90, os);
imgPart.attachFile(imageFile);
multipart.addBodyPart(imgPart);
message.setContent(multipart);
Transport.send(message); // send Message
System.out.println("Email Sent");
} catch (MessagingException | FileNotFoundException e) {
throw new RuntimeException(e);
}
I was thinking of converting the bitmap to a File object and then adding it to the body of the message, but I was thinking that there could be a more straightfirward and efficient way.
The Jakarta Mail FAQ is your best resource. See How do I send HTML mail that includes images?. That describes 3 choices:
Link image to web site, which I doubt works for you.
Inline the image <img src="data:image/jpeg;base64,base64-encoded-data-here" />
Construct a multipart/related message as you are doing.
The issue, as seen from the code, was that I was adding the text to the multipart, then the image (effectively overriding the text), and then I was assigning the multipart to the message. The solution was to add the text, using addBodyPart(text), and then use addBodyPart(image). After that, I could use setContent(multipart) to properly assign the text and image to the email.
// Add the generated QR code bitmap here
Multipart multipart = new MimeMultipart("related");
MimeBodyPart imgPart = new MimeBodyPart();
// Set the cache path and generate the new file image
String mFilePath = mContext.getCacheDir().toString();
File file = new File(mFilePath, FILE_NAME);
OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
// TITLE
message.setSubject("Workside Verification Service");
// TEXT
MimeBodyPart txtPart = new MimeBodyPart();
txtPart.setContent("Welcome to Workside! \n\nPlease proceed by scanning the QR code provided using the Workside application available in the Google Play store.\n\n\n"
+ "Regards,\n\nThe Workside Team", "text/plain");
// ADD TEXT
multipart.addBodyPart(txtPart);
// Generate image using the QR Bitmap, and attach it
mBitmapQR.compress(Bitmap.CompressFormat.JPEG, 90, os);
imgPart.attachFile(mFilePath + FILE_NAME);
// ADD IMAGE
multipart.addBodyPart(imgPart);
message.setContent(multipart);
I am trying to use the Google Gmail API (Java) to create an email that contains multiple attachments. Using the code below, I am able to send multiple attachments that are embedded within a MimeMessage if the attachments total less than 5MB (Google's threshold for simple file upload).
com.google.api.services.gmailGmail service = (... defined above ...)
javax.mail.internet.MimeMessage message = (... defined above with attachments embedded ...)
// Send the email
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
mimeMessage.writeTo(buffer);
byte[] bytes = buffer.toByteArray();
String encodedEmail = Base64.encodeBase64URLSafeString(bytes);
Message message = new Message();
message.setRaw(encodedEmail);
message = service.users().messages().send("me", message).execute();
However, I am unable to figure out how to correctly attach multiple files to an email using the Gmail Java API. The method below looks promising, but it appears to only accept 1 File/InputStream (mediaContent).
Gmail.Users.Messages.Send send(userId, Message content, AbstractInputStreamContent mediaContent)
Anyone know how to correctly implement a multi-file upload using the API?
As you correctly stated, the maximum attachment size for Simple file upload is 5 MB
Conclusion:
You need to to use Multipart upload or Resumable upload.
A sample sending an email with a multipart upload:
public static MimeMessage createEmailWithAttachment(String to, String from, String subject,
String bodyText,String filePath) throws MessagingException{
File file = new File(filePath);
Properties props = new Properties();
Session session = Session.getDefaultInstance(props, null);
MimeMessage email = new MimeMessage(session);
Multipart multipart = new MimeMultipart();
InternetAddress tAddress = new InternetAddress(to);
InternetAddress fAddress = new InternetAddress(from);
email.setFrom(fAddress);
email.addRecipient(javax.mail.Message.RecipientType.TO, tAddress);
email.setSubject(subject);
if (file.exists()) {
source = new FileDataSource(filePath);
messageFilePart = new MimeBodyPart();
messageBodyPart = new MimeBodyPart();
try {
messageBodyPart.setText(bodyText);
messageFilePart.setDataHandler(new DataHandler(source));
messageFilePart.setFileName(file.getName());
multipart.addBodyPart(messageBodyPart);
multipart.addBodyPart(messageFilePart);
email.setContent(multipart);
} catch (MessagingException e) {
e.printStackTrace();
}
}else
email.setText(bodyText);
return email;
}
Here you can find many other useful samples for sending emails with the Gmail API in Java.
It turns out that my MimeMessage was generated correctly, however, if the attachments included in the MimeMessage are larger than 5MB, you need to use a different Gmail API send() method. The API docs are incredibly confusing because they appear to state that you need to make multiple calls to rest endpoints to upload multiple files. It turns out that the Gmail Java Api does all the for you based off the MimeMessage submitted.
Below is a code snippet that shows how to use the two methods: "simple upload" and "multipart upload".
com.google.api.services.gmailGmail service = (... defined above ...)
javax.mail.internet.MimeMessage message = (... defined above with attachments embedded ...)
/**
* Send email using Gmail API - dynamically uses simple or multipart send depending on attachments size
*
* #param mimeMessage MimeMessage (includes any attachments for the email)
* #param attachments the Set of files that were included in the MimeMessage (if any). Only used to calculate total size to see if we should use "simple" send or need to use multipart upload.
*/
void send(MimeMessage mimeMessage, #Nullable Set<File> attachments) throws Exception {
Message message = new Message();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
mimeMessage.writeTo(buffer);
// See if we need to use multipart upload
if (attachments!=null && computeTotalSizeOfAttachments(attachments) > BYTES_5MB) {
ByteArrayContent content = new ByteArrayContent("message/rfc822", buffer.toByteArray());
message = service.users().messages().send("me", null, content).execute();
// Otherwise, use "simple" send
} else {
String encodedEmail = Base64.encodeBase64URLSafeString(buffer.toByteArray());
message.setRaw(encodedEmail);
message = service.users().messages().send("me", message).execute();
}
System.out.println("Gmail Message: " + message.toPrettyString());
}
This question already has answers here:
Launch Outlook to compose a message with subject and attachment by Outlook's command line switches
(3 answers)
Closed 6 years ago.
I need to implement the below logic using java.
--> When i click on a button, MS Outlook need to get opened with To,CC,Subject and attachment.
We can use mailto for doing this but we can't add attachment if we use mailto.
i need to add multiple attachment from a shared folder to MS outlook
Please help me.
Using switched it is possible to have single attachment but i need to open outlook with 2+ attachment and send button should be available so that user can send the mail
Use JavaMail to create a multipart mime message with your To, CC, Subject and attachment. Then instead of transporting the message call saveChanges and writeTo and store the email to the file system.
There is an undocumented /eml switch that can be used to open the MIME standard format. For example, outlook /eml filename.eml There is a documented /f switch which will open msg files. For example outlook /f filename.msg The x-unsent can be used to toggle the send button.
Here is an example to get you started:
public static void main(String[] args) throws Exception {
//Create message envelope.
MimeMessage msg = new MimeMessage((Session) null);
msg.addFrom(InternetAddress.parse("you#foo.com"));
msg.setRecipients(Message.RecipientType.TO,
InternetAddress.parse("support#bar.com"));
msg.setRecipients(Message.RecipientType.CC,
InternetAddress.parse("manager#baz.com"));
msg.setSubject("Hello Outlook");
//msg.setHeader("X-Unsent", "1");
MimeMultipart mmp = new MimeMultipart();
MimeBodyPart body = new MimeBodyPart();
body.setDisposition(MimePart.INLINE);
body.setContent("This is the body", "text/plain");
mmp.addBodyPart(body);
MimeBodyPart att = new MimeBodyPart();
att.attachFile("c:\\path to file.attachment");
mmp.addBodyPart(att);
msg.setContent(mmp);
msg.saveChanges();
File resultEmail = File.createTempFile("test", ".eml");
try (FileOutputStream fs = new FileOutputStream(resultEmail)) {
msg.writeTo(fs);
fs.flush();
fs.getFD().sync();
}
System.out.println(resultEmail.getCanonicalPath());
ProcessBuilder pb = new ProcessBuilder();
pb.command("cmd.exe", "/C", "start", "outlook.exe",
"/eml", resultEmail.getCanonicalPath());
Process p = pb.start();
try {
p.waitFor();
} finally {
p.getErrorStream().close();
p.getInputStream().close();
p.getErrorStream().close();
p.destroy();
}
}
You'll have to handle clean up after the email client is closed.
You also have to think about the security implications of email messages being left on the file system.
I am trying to send the mail using JavaMailSender which include the html content but instead of the rendered html in the email i am getting the html code itself in the mail i.e
Method used to send email
public void sendMimeMessage(String from, String to, String subject, String messageBody, String... cc) {
MimeMessage message = mailSender.createMimeMessage()
try {
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(from)
helper.setSentDate(new Date())
helper.setSubject(subject)
helper.setText(messageBody, true)
helper.setTo(to)
helper.setCc(cc)
mailSender.send(message)
log.debug("Email successfully sent to <${to}> with cc <${cc}> and with subject <${subject}> and Email body: ${messageBody}")
} catch (Exception exception) {
exception.printStackTrace()
log.error("Email to <${to}> with subject <${subject}> could not be sent due to: ", exception)
}
}
Any help would be appreciated.
This might help you.
You can use Apache velicity, or can see my Answer.
Sample code:
JavaMailSenderImpl sender = new JavaMailSenderImpl();
sender.setHost("mail.host.com");
MimeMessage message = sender.createMimeMessage();
// use the true flag to indicate you need a multipart message
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setTo("test#host.com");
// use the true flag to indicate the text included is HTML
helper.setText("<html><body><img src='cid:identifier1234'></body></html>", true);
// let's include the infamous windows Sample file (this time copied to c:/)
FileSystemResource res = new FileSystemResource(new File("c:/Sample.jpg"));
helper.addInline("identifier1234", res);
sender.send(message);
This worked for me.
Step 1. Construct the messageBody as follows:
Let suppose you need a HTML content in mail like shown below
**SERIAL NO PROCESS_INSTANCE_ID USONUMBER**
1 TSV00876 N89876
2 LMNV0083 V89876
Let suppose you have list from where you are going to populate above columns.
List<Report> list = xyzService.getReport(); **//returns list of Report**
StringBuilder buf = new StringBuilder();
buf.append("<!doctype html>\n");
buf.append("<html lang='en'>\n");
buf.append("<head>\n");
buf.append("<meta charset='utf-8'>\n");
buf.append("<title>Report</title>\n");
buf.append("</head>\n");
buf.append("<body>" +
"<table border ='1'>" + "<tr>" +
"<th>SERIAL NO</th>" +
"<th>PROCESS_INSTANCE_ID</th>" +
"<th>USONUMBER</th>"+
"</tr>\n");
for (int i = 0; i < list.size(); i++) {
buf.append("<tr><td>").
append(list.get(i)).getSerialNo().append("</td><td>").
append(list.get(i).getProcessInstanceId()).append("</td><td>").
append(list.get(i).getUsoNumber()).append("</td><td>").
append("</td></tr>\n");
}
buf.append("</table>\n" +
"</body>\n" +
"</html>");
String messageBody = buf.toString();
Step 2. pass this string messageBody in your method sendMimeMessage() and set
MimeMessageHelper as shown below.
MimeMessage message = mailSender.createMimeMessage()
MimeMessageHelper helper = new MimeMessageHelper(message,MimeMessageHelper.MULTIPART_MODE_MIXED_RELATED,StandardCharsets.UTF_8.name());
helper.setText(messageBody, true);
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);
}