Attach a MimeMessage to another MimeMessage - java

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);

Related

Inline image shown as attachment : JavaMail

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/>

Outlook can't show image into MimeMessage

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

JavaMail attachment and body issue

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);

Java email content is empty

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());

How to attach multiple files to an email using JavaMail?

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);

Categories