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 prepare my message as MimeMessage and try it open in different mail clients. In all client my message looks good but in Outlook and in another one, it looks wrong
...
MimeMessage mimeMessage = new MimeMessage(session);
// Text version
final MimeBodyPart textPart = new MimeBodyPart();
textPart.setContent(email.getPlainMessage(), "text/plain");
// HTML version
final MimeBodyPart htmlPart = new MimeBodyPart();
htmlPart.setContent(email.getMessage(), "text/html");
//logo
PreencodedMimeBodyPart logo = new PreencodedMimeBodyPart(BASE_64_ENCODING);
logo.setHeader("Content-Type", IMAGE_PNG_CONTENT_TYPE + "; name=\"logo.png\"");
logo.setHeader("Content-ID", "<logo.png#01CFFF81.C72F8000>");
logo.setHeader("Content-Disposition", "inline; filename=\"logo.png\"");
logo.setHeader("Content-Transfer-Encoding", BASE_64_ENCODING);
logo.setContent(ENCODED_LOGO, IMAGE_PNG_CONTENT_TYPE);
// Create the Multipart. Add BodyParts to it.
final Multipart mp = new MimeMultipart("alternative");
mp.addBodyPart(logo);
mp.addBodyPart(textPart);
mp.addBodyPart(htmlPart);
if (Objects.nonNull(email.getFilesToAttach())) {
for (String filename : email.getFilesToAttach()) {
MimeBodyPart messageBodyPart = new MimeBodyPart();
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename.substring(filename.lastIndexOf(File.separator) + 1));
mp.addBodyPart(messageBodyPart);
}
}
// Set Multipart as the message's content
mimeMessage.setContent(mp);
mimeMessage.setSubject(email.getSubject());
mimeMessage.setFrom(new InternetAddress(emailConfig.getNoReplyEmailAddress()));
if (!emailConfig.getNoReplyEmailAddress().equals(email.getFromAddress())) {
List<Address> replyTo = Arrays.asList(new InternetAddress(email.getFromAddress()));
mimeMessage.setReplyTo(replyTo.toArray(new Address[replyTo.size()]));
}
mimeMessage.addRecipient(MimeMessage.RecipientType.TO, new InternetAddress(email.getToAddress()));
mimeMessage.saveChanges();
...
And when I send it in outlook I see my logo as
but in another mail clients it looks good
I am using below code to attach a pdf file to mail (JAVAMAIL). this postion works perfectly and adds attachment to my mail but this mail does not have any body.
Multipart multipart = new MimeMultipart();
msg.setContent(multipart);
DataSource source = new FileDataSource(pdf);
MimeBodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(pdf.getName().toString());
multipart.addBodyPart(messageBodyPart);
msg.setContent(multipart);
when i add below lines to my code it removes attachment and send me mail containing the text only.
msg.setText(body);
please help me to add both attachment and test body to my mail.
The problem is that if you want to send a message with attachments, then you need to have a part for your message, and a part for your attachment.
By calling setText in the message, you are throwing away the multipart you set earlier.
Your message needs to have an hierarchy that looks like this (more nesting is necessary if you want to have a plain text and html message):
MimeMessage
+- MimeMultiPart
+- MimeBodyPart (message)
+- MimeBodyPart (attachment)
For example
MimeMessage message = new MimeMessage(session);
MimeMultiPart multiPart = new MimeMultiPart();
MimeBodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setText(body);
multiPart.addBodyPart(messageBodyPart);
MimeBodyPart attachment = new MimeBodyPart();
attachment.setDataHandler(new DataHandler(source));
attachment.setDisposition(Part.ATTACHMENT);
attachment.setFileName(pdf.getName().toString());
multipart.addBodyPart(attachment);
message.setContent(multiPart);
I have added below lines to make it work.
Multipart multipart = new MimeMultipart();
msg.setContent(multipart);
DataSource source = new FileDataSource(pdf);
MimeBodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(pdf.getName().toString());
multipart.addBodyPart(messageBodyPart);
msg.setContent(multipart);
BodyPart htmlPart = new MimeBodyPart();
htmlPart.setContent(body, "text/html");
multipart.addBodyPart(htmlPart);
public static String sendMail(
String destino,
String texto,
String asunto,
byte[] formulario,
String nombre) {
Properties properties = new Properties();
try{
Session session = Session.getInstance(properties);
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("reminder#companyname.com.ar"));
//Cargo el destino
if(destino!= null && destino.length > 0 && destino[0].length() > 0 ){
for (int i = 0; i < destino.length; i++) {
message.addRecipient(Message.RecipientType.TO,new InternetAddress(destino[i]));
}
}
//message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
message.setSubject(asunto);
//I load the text and replace all the '&' for 'Enters' and the '#' for tabs
message.setText(texto.replaceAll("&","\n").replaceAll("#","\t"));
Transport.send(message);
return "Mensaje enviado con éxito";
}catch(Exception mex){
return mex.toString();
}
}
Hello everyone.
I was trying to figure out how can I attach the PDF sent by parameters as formulario in the code previously shown.
The company used to do the following trick for this matter but they need to change it for the one previously shown:
MimeBodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setText(
texto.replaceAll("&", "\n").replaceAll("#", "\t"));
//msg.setText(texto.replaceAll("&","\n").replaceAll("#","\t"));
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);
messageBodyPart = new MimeBodyPart();
messageBodyPart.setDataHandler(
new DataHandler(
(DataSource) new InputStreamDataSource(formulario,
"EDD",
"application/pdf")));
messageBodyPart.setFileName(nombre + ".pdf");
multipart.addBodyPart(messageBodyPart);
msg.setContent(multipart);
msg.saveChanges();
Transport transport = session.getTransport("smtp");
transport.connect(
"smtp.gmail.com",
"reminder#companyname.com.ar",
"companypassword");
transport.sendMessage(msg, msg.getAllRecipients());
transport.close();
return "Mensaje enviado con éxito";
} catch (Exception mex) {
return mex.toString();
Since you already can send emails, the adjust your code and add the following part to your code
// Create a default MimeMessage object.
Message message = new MimeMessage(session);
// Set From: header field of the header.
message.setFrom(new InternetAddress(from));
// Set To: header field of the header.
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse(to));
// Set Subject: header field
message.setSubject("Testing Subject");
// Create the message part
BodyPart messageBodyPart = new MimeBodyPart();
// Now set the actual message
messageBodyPart.setText("This is message body");
// Create a multipar message
Multipart multipart = new MimeMultipart();
// Set text message part
multipart.addBodyPart(messageBodyPart);
// Part two is attachment
messageBodyPart = new MimeBodyPart();
String filename = "/home/file.pdf";
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
multipart.addBodyPart(messageBodyPart);
// Send the complete message parts
message.setContent(multipart);
// Send message
Transport.send(message);
System.out.println("Sent message successfully....");
original code taken from here
Is formulario a byte array in both cases? If so, just rewrite the first block of code to construct the message using the technique in the second block of code. Or replace InputStreamDataSource with ByteArrayDataSource in the new version.
The sending email with attachment is similar to sending email but here the additional functionality is with message sending a file or document by making use of MimeBodyPart, BodyPart classes.
The process for sending mail with attachment involves session object, MimeBody, MultiPart objects. Here the MimeBody is used to set the text message and it is carried by MultiPart object. Because of MultiPart object here sending attachment.
try {
// Create a default MimeMessage object.
Message message = new MimeMessage(session);
// Set From: header field of the header.
message.setFrom(new InternetAddress(from));
// Set To: header field of the header.
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse(to));
// Set Subject: header field
message.setSubject("Attachment");
// Create the message part
BodyPart messageBodyPart = new MimeBodyPart();
// Now set the actual message
messageBodyPart.setText("Please find the attachment below");
// Create a multipar message
Multipart multipart = new MimeMultipart();
// Set text message part
multipart.addBodyPart(messageBodyPart);
// Part two is attachment
messageBodyPart = new MimeBodyPart();
String filename = "D:/test.PDF";
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
multipart.addBodyPart(messageBodyPart);
// Send the complete message parts
message.setContent(multipart);
// Send message
Transport.send(message);
System.out.println("Email Sent Successfully !!");
} catch (MessagingException e) {
throw new RuntimeException(e);
}
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);