I am trying to send an email with an inline image, but the image is getting send as an attachment instead of inline.
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
try {
String filename = "logo.jpeg";
mimeMessage.setFrom(new InternetAddress("Bridge"));
mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
mimeMessage.setSubject(subject);
MimeMultipart multipart = new MimeMultipart();
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setContent(content, "text/html");
multipart.addBodyPart(messageBodyPart);
messageBodyPart = new MimeBodyPart();
DataSource fds = new ByteArrayDataSource(IOUtils.toByteArray(resourceFile.getInputStream()), MediaType.IMAGE_JPEG_VALUE);
messageBodyPart.setDataHandler(new DataHandler(fds));
messageBodyPart.setDisposition(MimeBodyPart.INLINE);
messageBodyPart.setFileName(filename);
messageBodyPart.setHeader("Content-ID", "<logoimg>");
messageBodyPart.setHeader("Content-Type", MediaType.IMAGE_JPEG_VALUE);
multipart.addBodyPart(messageBodyPart);
mimeMessage.setContent(multipart);
mimeMessage.saveChanges();
javaMailSender.send(mimeMessage);
} catch (MailException | MessagingException | IOException e) {
log.warn("Email could not be sent to user '{}'", to, e);
}
And here is my HTML code for the image:
<img width="100" height="50" src="|cid:logoimg|" alt="phoenixlogo"/>
I have tried all the multipart types: "mixed", "relative", "alternative" but couldn't get it to work.
Here is image for same:
You don't want an inline image, you want an html body that references an attached image. For that you need a multipart/related message. See the JavaMail FAQ.
You need to add a separate MimeBodyPart: For Example
BodyPart imgPart = new MimeBodyPart();
DataSource ds = new FileDataSource("D:/image.jpg");
imgPart.setDataHandler(new DataHandler(ds));
imgPart.setHeader("Content-ID", "<the-img-1>");
multipart.addBodyPart(imgPart);
Then in the html you refer to the Image as:
<br>" + "<img src=\"cid:the-img-1\"/><br/>
I have a MimeMessage A and would like to add another MimeMessage B as an attachment.
My (not working) attempt:
MimeBodyPart mimeBodyPart = new MimeBodyPart();
mimeBodyPart.setContent(base64mimeMessage, "message/rfc822");
mimeBodyPart.setHeader("Content-Transfer-Encoding", "base64");
multipart.addBodyPart(mimeBodyPart);
Which causes an java.io.IOException: unsupported object at com.sun.mail.handlers.message_rfc822.writeTo later when i try to sign or encrypt the result.
Maybe it is helpful for somebody else, so here is a working solution
MimeBodyPart mimeBodyPart = new MimeBodyPart();
DataSource dataSource = new ByteArrayDataSource(Base64.decode(itemAttachment.getMimeContent(), Base64.DEFAULT), "message/rfc822");
mimeBodyPart.setDataHandler(new DataHandler(dataSource));
multipart.addBodyPart(mimeBodyPart);
Session session = Session.getInstance(new Properties());
MimeMessage mimeMessageToAttach = new MimeMessage(session);
MimeBodyPart attachment = new MimeBodyPart();
String contentType = "message/rfc822; name=mymail.eml";
attachment.setContent(mimeMessageToAttach, contentType);
MimeMultipart multipart = new MimeMultipart();
multipart.addBodyPart(mimeBodyPart);
I have snippet of codes where I send out email with excel file attachment. All works fine where I can see title and even the file attachment. The only thing does not appear is the email content. I have tested that my emailContent variable is not empty. What else can I do to make it appear ? I have even enabled this line of codes messageBodyPart.setText(emailContent); yet the same.
But if enabled this part multipart1.addBodyPart(emailContent); I get error
error: no suitable method found for addBodyPart(String)
multipart1.addBodyPart(emailContent);
try
{
Message emailMessage = new MimeMessage(mailSession);
emailMessage.setFrom(new InternetAddress(origin1));
emailMessage.addRecipient(Message.RecipientType.TO,new InternetAddress(receiptnt1));
emailMessage.addRecipient(Message.RecipientType.TO,new InternetAddress(receiptnt2));
emailMessage.setRecipients(Message.RecipientType.CC,InternetAddress.parse(cc1));
emailMessage.setSubject(emailTitle);
emailMessage.setText(emailContent);
BodyPart messageBodyPart = new MimeBodyPart();
// Fill the message
//messageBodyPart.setText(emailContent);*/
Multipart multipart1 = new MimeMultipart();
// Part two is attachment
messageBodyPart = new MimeBodyPart();
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
multipart1.addBodyPart(messageBodyPart);
// Put parts in message
emailMessage.setContent(multipart1);
//System.out.println("\n\nSend email :"+eMArray[0]);
transport.sendMessage(emailMessage, emailMessage.getAllRecipients());
}
catch (Exception e)
{
System.out.println("Transport Problem");
e.printStackTrace();
}
You have initialized
BodyPart messageBodyPart = new MimeBodyPart();
Two times. And before the second initialization you're adding the body contents.
So remove the line
messageBodyPart = new MimeBodyPary();
Line and it will work fine.
Use the following code.
Message emailMessage = new MimeMessage(mailSession);
emailMessage.setFrom(new InternetAddress(origin1));
emailMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(receiptnt1));
emailMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(receiptnt2));
emailMessage.setRecipients(Message.RecipientType.CC, InternetAddress.parse(cc1));
emailMessage.setSubject(emailTitle);
// emailMessage.setText(emailContent);
Multipart multipart1 = new MimeMultipart();
BodyPart messageBodyPart = new MimeBodyPart();
// Fill the message
messageBodyPart.setText(emailContent);
// Part two is attachment
BodyPart attachment = new MimeBodyPart();
DataSource source = new FileDataSource(filename);
attachment.setDataHandler(new DataHandler(source));
attachment.setFileName(filename);
multipart1.addBodyPart(attachment);
multipart1.addBodyPart(messageBodyPart);
// Put parts in message
emailMessage.setContent(multipart1);
//System.out.println("\n\nSend email :"+eMArray[0]);
transport.sendMessage(emailMessage, emailMessage.getAllRecipients());
Hi I have the following code:
MimeMessage msg = new MimeMessage(session);
InternetAddress addressFrom = new InternetAddress("krao346789#gmail.com");
msg.setFrom(addressFrom);
InternetAddress[] addressTo = new InternetAddress[sendTo.length];
for (int i = 0; i < sendTo.length; i++) {
addressTo[i] = new InternetAddress(sendTo[i]);
}
msg.setRecipients(Message.RecipientType.TO, addressTo);
// Setting the Subject and Content Type
msg.setSubject(emailSubjectTxt);
/*Image part*/
MimeMultipart multipart = new MimeMultipart("related");
// first part (the html)
BodyPart messageBodyPart = new MimeBodyPart();
String htmlText = "<H1>Hello</H1><img src=\"cid:image\">";
messageBodyPart.setContent(htmlText, "text/html");
// add it
multipart.addBodyPart(messageBodyPart);
// second part (the image)
messageBodyPart = new MimeBodyPart();
String contextPath=request.getContextPath();
System.out.println("contextpath"+contextPath);
File contextDir = new File(contextPath);
System.out.println("contextDir"+contextDir);
File emailImage = new File(contextDir, "/images/sample.jpeg");
System.out.println("emailImage"+emailImage);
DataSource fds = new FileDataSource(emailImage);
//System.out.println("fds"+fds.getName());
messageBodyPart.setDataHandler(new DataHandler(fds));
messageBodyPart.setHeader("Content-ID","<image>");
// add it
multipart.addBodyPart(messageBodyPart);
// put everything together
msg.setContent(multipart);
Transport.send(msg);
}
It works fine if I use
DataSource fds = new FileDataSource("C:\\images\\sample.jpeg");
instead of
DataSource fds = new FileDataSource(emailImage);
But I want to access image from WebContent->images.
I get java.lang.NullPointerException when I run this.
If you would like to use in web application. First, you have to upload your attachment file to server as InputStream and then create attachment file by using this InputStream.
Solved: Use getRealPath();
Its working fine now.
File contextDir = new File(request.getRealPath("/images/sample.jpeg"));
DataSource fds = new FileDataSource(contextDir);
If images/sample.jpeg is from your resources folder then try this :
DataSource fds = new FileDataSource(getFileHandle("images/sample.jpeg"));
public static File getFileHandle(String fileName){
return new File(YourClassName.class.getClassLoader().getResource(fileName).getFile());
}
in case of non static reference:
return new File(getClass().getClassLoader().getResource(fileName).getFile());
The following Java code is used to attach a file to an email. I want to send multiple files attachments through email. Any suggestions would be appreciated.
public class SendMail {
public SendMail() throws MessagingException {
String host = "smtp.gmail.com";
String Password = "mnmnn";
String from = "xyz#gmail.com";
String toAddress = "abc#gmail.com";
String filename = "C:/Users/hp/Desktop/Write.txt";
// Get system properties
Properties props = System.getProperties();
props.put("mail.smtp.host", host);
props.put("mail.smtps.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
Session session = Session.getInstance(props, null);
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.setRecipients(Message.RecipientType.TO, toAddress);
message.setSubject("JavaMail Attachment");
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setText("Here's the file");
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);
messageBodyPart = new MimeBodyPart();
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
multipart.addBodyPart(messageBodyPart);
message.setContent(multipart);
try {
Transport tr = session.getTransport("smtps");
tr.connect(host, from, Password);
tr.sendMessage(message, message.getAllRecipients());
System.out.println("Mail Sent Successfully");
tr.close();
} catch (SendFailedException sfe) {
System.out.println(sfe);
}
}
}`
Well, it's been a while since I've done JavaMail work, but it looks like you could just repeat this code multiple times:
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
multipart.addBodyPart(messageBodyPart);
For example, you could write a method to do it:
private static void addAttachment(Multipart multipart, String filename)
{
DataSource source = new FileDataSource(filename);
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
multipart.addBodyPart(messageBodyPart);
}
Then from your main code, just call:
addAttachment(multipart, "file1.txt");
addAttachment(multipart, "file2.txt");
etc
UPDATE (March 2020)
With the latest JavaMail™ API (version 1.6 at the moment, JSR 919), things are much simpler:
void attachFile(File file)
void attachFile(File file, String contentType, String encoding)
void attachFile(String file)
void attachFile(String file, String contentType, String encoding)
Useful reading
Here is a nice and to the point tutorial with the complete example:
JavaMail - How to send e-mail with attachments
Multipart mp = new MimeMultipart();
MimeBodyPart mbp1 = new MimeBodyPart();
mbp1.setContent(body,"text/html");
mp.addBodyPart(mbp1);
if(filename!=null)
{
MimeBodyPart mbp2 = null;
FileDataSource fds =null;
for(int counter=0;counter<filename.length;counter++)
{
mbp2 = null;
fds =null;
mbp2=new MimeBodyPart();
fds = new FileDataSource(filename[counter]);
mbp2.setDataHandler(new DataHandler(fds));
mbp2.setFileName(fds.getName());
mp.addBodyPart(mbp2);
}
}
msg.setContent(mp);
msg.setSentDate(new Date());
Transport.send(msg);
just add another block with using the filename of the second file you want to attach and insert it before the message.setContent(multipart) command
messageBodyPart = new MimeBodyPart();
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
multipart.addBodyPart(messageBodyPart);
Have Array list al which has the list of attachments you need to mail and use the below given code
for(int i=0;i<al.size();i++)
{
System.out.println(al.get(i));
messageBodyPart = new MimeBodyPart();
DataSource source = new FileDataSource((String)al.get(i));
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName((String)al.get(i));
multipart.addBodyPart(messageBodyPart);
message.setContent(multipart);
}
File f = new File(filepath);
File[] attachments = f.listFiles();
// Part two is attachment
for( int i = 0; i < attachments.length; i++ ) {
if (attachments[i].isFile() && attachments[i].getName().startsWith("error")) {
messageBodyPart = new MimeBodyPart();
FileDataSource fileDataSource =new FileDataSource(attachments[i]);
messageBodyPart.setDataHandler(new DataHandler(fileDataSource));
messageBodyPart.setFileName(attachments[i].getName());
messageBodyPart.setContentID("<ARTHOS>");
messageBodyPart.setDisposition(MimeBodyPart.INLINE);
multipart.addBodyPart(messageBodyPart);
}
}
for (String fileName: files) {
MimeBodyPart messageAttachmentPart = new MimeBodyPart();
messageAttachmentPart.attachFile(fileName);
multipart.addBodyPart(messageAttachmentPart);
}
You have to make sure that you are creating a new mimeBodyPart for each attachment. The object is being passed by reference so if you only do :
MimeBodyPart messageAttachmentPart = new MimeBodyPart();
for (String fileName: files) {
messageAttachmentPart.attachFile(fileName);
multipart.addBodyPart(messageAttachmentPart);
}
it will attach the same file X number of times
#informatik01 posted an answer above with the link to the documentation where there is an example of this
Just add more files to the multipart.
This is woking 100% with Spring 4+. You will have to enable less secure option on your gmail account. Also you will need the apache commons package:
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
#GetMapping("/some-mapping")
public void mailMethod(#RequestParam CommonsMultipartFile attachFile, #RequestParam CommonsMultipartFile attachFile2) {
Properties mailProperties = new Properties();
mailProperties.put("mail.smtp.auth", true);
mailProperties.put("mail.smtp.starttls.enable", true);
mailProperties.put("mail.smtp.ssl.enable", true);
mailProperties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
mailProperties.put("mail.smtp.socketFactory.fallback", false);
JavaMailSenderImpl javaMailSenderImpl = new JavaMailSenderImpl();
javaMailSenderImpl.setJavaMailProperties(mailProperties);
javaMailSenderImpl.setHost("smtp.gmail.com");
javaMailSenderImpl.setPort(465);
javaMailSenderImpl.setProtocol("smtp");
javaMailSenderImpl.setUsername("*********#gmail.com");
javaMailSenderImpl.setPassword("*******");
javaMailSenderImpl.setDefaultEncoding("UTF-8");
List<CommonsMultipartFile> attachments = new ArrayList<>();
attachments.add(attachFile);
attachments.add(attachFile2);
javaMailSenderImpl.send(mimeMessage -> {
MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
messageHelper.setTo(emailTo);
messageHelper.setSubject(subject);
messageHelper.setText(message);
if (!attachments.equals("")) {
for (CommonsMultipartFile file : attachments) {
messageHelper.addAttachment(file.getOriginalFilename(), file);
}
}
});
}
Multipart multipart = new MimeMultipart("mixed");
for (int alen = 0; attlen < attachments.length; attlen++)
{
MimeBodyPart messageAttachment = new MimeBodyPart();
fileName = ""+ attachments[attlen];
messageAttachment.attachFile(fileName);
messageAttachment.setFileName(attachment);
multipart.addBodyPart(messageAttachment);
}
After Java Mail 1.3 attaching file more simpler,
Just use MimeBodyPart methods to attach file directly or from a filepath.
MimeBodyPart messageBodyPart = new MimeBodyPart();
//messageBodyPart.attachFile(String filePath);
messageBodyPart.attachFile(File file);
multipart.addBodyPart(messageBodyPart);
Try this to read the file name from array
MimeBodyPart messageBodyPart = new MimeBodyPart();
Multipart multipart = new MimeMultipart();
for(int i = 0 ; i < FilePath.length ; i++){
info("Attching the file + "+ FilePath[i]);
messageBodyPart.attachFile(FilePath[i]);
multipart.addBodyPart(messageBodyPart);
}
message.setContent(multipart);
I do have a better alternative for sending Multiple files in a single mail off course. Mutipart class allows us to attain this feature quite easily. If you may not have any info about it then read it from here : https://docs.oracle.com/javaee/6/api/javax/mail/Multipart.html
The Multipart class provides us two same-name methods with different parameters off course, i.e. addBodyPart(BodyPart part) and addBodyPart(BodyPart part, int index). For 1 single file we may use the first method and for mutiple files we may use the second method (which takes two parameters).
MimeMessage message = new MimeMessage(session);
Multipart multipart = new MimeMultipart();
message.setFrom(new InternetAddress(username));
for (String email : toEmails) {
message.addRecipient(Message.RecipientType.BCC, new InternetAddress(email));
}
message.setSubject(subject);
BodyPart messageBodyPart1 = new MimeBodyPart();
messageBodyPart1.setText(typedMessage);
multipart.addBodyPart(messageBodyPart1, i);
i = i + 1;
for (String filename : attachedFiles) {
MimeBodyPart messageBodyPart2 = new MimeBodyPart();
messageBodyPart2.attachFile(filename);
multipart.addBodyPart(messageBodyPart2, i);
i = i + 1;
}
message.setContent(multipart);
Transport.send(message);
Below is working for me:
List<String> attachments = new ArrayList<>();
attachments.add("C:/Users/dell/Desktop/file1.txt");
attachments.add("C:/Users/dell/Desktop/file2.txt");
attachments.add("C:/Users/dell/Desktop/file3.txt");
attachments.add("C:/Users/dell/Desktop/file4.txt");
attachments.add("C:/Users/dell/Desktop/file5.txt");
MimeMessage msg = new MimeMessage(session);
if (attachments !=null && !attachments.isEmpty() ) {
MimeBodyPart attachmentPart = null;
Multipart multipart = new MimeMultipart();
for(String attachment : attachments) {
attachmentPart = new MimeBodyPart();
attachmentPart.attachFile(new File(attachment));
multipart.addBodyPart(attachmentPart);
}
multipart.addBodyPart(textBodyPart);
msg.setContent(multipart);
}
Transport.send(msg);