Let it be clear that Java is working correctly. The problem is with the programmer!
I need to add 3 attachments to an email (1 zip, 1 png, 1 jpeg). Initially I wrote code that can add each item on it's own - and it works. Then to add all 3 items at the same time I took the same code (with very minor modifications) and put it in a for loop. This is where I am having an issue. The loop adds 3 attachments to the email, but the problem is that all the attachments are same identical attachment. Specifically, the first two attachments that should be attached in the first 2 iterations of the for loop are not attached, and the third attachment (the attachment that is up to bat at the third iteration) is attached 3 times.
I read the Java docs, I tried all kinds of changes and I am having a hard time understanding where I am going wrong. The reality is that I don't have enough programming ability to move forward. I'm stuck. Any advice would be greatly appreciated! I attached most of the class, but the real problem is in the for loop - why are all 3 unique objects not being attached?
Thanks in advance.
try
{
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(userLogin));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(primaryRecipient));
MimeBodyPart bodyPart = new MimeBodyPart(); //container to hold the email contents (body only - the text)
bodyPart.setText(emailBody);
MimeMultipart multipart = new MimeMultipart();
multipart.addBodyPart(bodyPart);
MimeBodyPart mimePart = new MimeBodyPart();
String filename; //hold the current path
FileDataSource resource;//object to grab the physical resource
for(int i = 0; i < itemsToAttach.length; i++)
{
filename = itemsToAttach[i];
System.out.println("Test: " + itemsToAttach[i]);//#############################test only
resource = new FileDataSource(filename);
mimePart.setDataHandler(new DataHandler(resource));
mimePart.setFileName(filename);//###########fix the long ugly name
multipart.addBodyPart(mimePart);
System.out.println("multipart contents: " + multipart.toString());
}
message.setContent(multipart);
message.setSubject(emailSubject);
Transport.send(message);
System.out.println("Sent message successfully....");
}
catch (MessagingException e)
{
throw new RuntimeException(e);
}
The output looks like this:
The file is present!
Sending cc to: mikexxxxxxx#hotmail.com
Sending bcc to: mikexxxxxx#gmail
Test: C:\Users\Mike\workspace\Z_ToTransfer\Assig4_SendEmails\part2_send_email_with_attachment\attachments\test attachments.zip
multipart contents: javax.mail.internet.MimeMultipart#164da25
Test: C:\Users\Mike\workspace\Z_ToTransfer\Assig4_SendEmails\part2_send_email_with_attachment\attachments\axiom.jpeg
multipart contents: javax.mail.internet.MimeMultipart#164da25
Test: C:\Users\Mike\workspace\Z_ToTransfer\Assig4_SendEmails\part2_send_email_with_attachment\attachments\another attachment.png
multipart contents: javax.mail.internet.MimeMultipart#164da25
Sent message successfully....
Looks like you are reusing the same object and it is getting overwritten on every iteration of the loop. Thant's why the only entry persists is the last mimepart when you send the message:
You can do following:
Create a different object of MimebodyPart for every new file:
MimeBodyPart[] mimePart = new MimeBodyPart[itemsToAttach.length];
String filename; //hold the current path
FileDataSource resource;//object to grab the physical resource
for(int i = 0; i < itemsToAttach.length; i++)
{
mimePart[i] = new MimeBodyPart();
filename = itemsToAttach[i];
System.out.println("Test: " + itemsToAttach[i]);//#############################test only
resource = new FileDataSource(filename);
mimePart[i].setDataHandler(new DataHandler(resource));
mimePart[i].setFileName(filename);//###########fix the long ugly name
multipart.addBodyPart(mimePart[i]);
System.out.println("multipart contents: " + multipart.toString());
}
Related
I tried in many ways to get the reply in same thread using outlook account and javamail api but iam not able to get reply in same thread instead iam getting as attachment.
I tried to copy whole content and save in current message even then iam getting as attachment, also tried to change the content disposition as inline still it didn't work
you can find the code below which i had tried.
Properties properties = new Properties();
Session emailSession = Session.getDefaultInstance(properties,null);
store = emailSession.getStore("imaps");
store.connect(host,mailbox_username, mailbox_password);
folder = store.getFolder("Inbox");
folder.open(Folder.READ_WRITE);
Message[] unreadMessages = folder.search(new FlagTerm(new Flags(Flags.Flag.SEEN),false));
if(unreadMessages.size()>0)
{
for (int i = 0; i < unreadMessages.length; i++)
{
log.info("retriving message "+(i+1))
Message message = unreadMessages[i]
Address[] froms = message.getFrom();
String senderEmailAddress =(froms[0]).getAddress();
if(senderEmailAddress.endsWith("#gmail.com"))
{
subject = message.getSubject()
log.info(message.getSubject())
}
else
{ //reply to same mail here we need to reply to the message
Message message2 = new MimeMessage(emailSession);
message2= (MimeMessage) message.reply(false);
message2.setSubject("RE: " + message.getSubject());
//message2.setFrom(new InternetAddress(from));
message2.setReplyTo(message.getReplyTo());
message2.addRecipient(Message.RecipientType.TO, new InternetAddress(senderEmailAddress));
BodyPart messageBodyPart = new MimeBodyPart();
content = "some reply message"
//multipart.addBodyPart(content);
messageBodyPart.setText(content);
Multipart multipart = new MimeMultipart("related");
multipart.addBodyPart(messageBodyPart);
messageBodyPart = new MimeBodyPart();
//messageBodyPart.setDataHandler(message.getDataHandler());
//bodyPart.setDataHandler(new DataHandler(ds));
//messageBodyPart.setHeader("Content-Type", "image/jpeg; name=image.jpg");
//messageBodyPart.setHeader("Content-ID", "<image>");
//messageBodyPart.setHeader("Content-Disposition", "inline");
//messageBodyPart.addBodyPart(bodyPart);
//msg.setContent(content);
messageBodyPart.setDisposition(MimeBodyPart.INLINE);
messageBodyPart.setContent(message, "message/rfc822");
messageBodyPart.setDataHandler(message.getDataHandler());
// Add part to multi part
multipart.addBodyPart(messageBodyPart);
// Associate multi-part with message
message2.setContent(multipart);
Transport t = emailSession.getTransport("smtp");
try {
t.connect(mailbox_username, mailbox_password);
t.sendMessage(message2, message2.getAllRecipients());
} finally {
t.close();
}
}
}
}
"inline" vs. "attachment" is just advice for the mail reader. Many ignore the device, or aren't capable of displaying all content types inline.
If you want the text of the original message to appear in the body of the reply message (e.g., indented with ">"), you need to extract the original text and reformat it appropriately, adding it to the text of the reply, then set that new String as the content of the reply message.
I am sending multi-part message using JavaMailSenderImpl.
I have following code to send mail.
MimeMessage mimeMessage = this.mailSender.createMimeMessage();
MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true);
message.setSubject("Testing");
message.setTo(getMktTemplateErrorsReportingEmailAddress());
message.setText("Hello testing.", emailTemplate.isHtml());
if (StringUtils.isNotBlank(fileName)) {
FileSystemResource file = new FileSystemResource(fileName);
message.addAttachment(file.getFilename(), file);
}
this.mailSender.send(mimeMessage);
In send() method ..
Object cObj = mimeMessage.getContent();
if(cObj instanceof Multipart) {
Multipart content = (Multipart)cObj ;
int count = content.getCount();
for(int i=0; i<count; i++) {
BodyPart part = content.getBodyPart(i);
//need to append some info if part is text.
}
My understanding is first part contains message as String and second as fils (attachment). while I am seeing as first part is MimeMultipart.
eg:
javax.mail.internet.MimeMultipart#79a3195f
java.io.FileInputStream#14bedd31
Now my question is How to replace part after appending information.
eg: First part is "Hello testing.". I want to append with as some system info. for eg: As Hello testing. IP: 192.23.22.22 . So after appending how to replace this with first part and send.
Don't know how to do this.
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.
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);
}
I have 2 files in the directory "bar" for testing. from the code below, it is suppose to send all files in that directory as email attachments. The problem is that when I send them, I get duplicates of one file in my email. I did have it working correctly once before for testing, but I dont remember what I might have changed.
Does anyone recognize what might be wrong with my code or why I instead of sending all the files in the directory, I get one file multiple times in my email?
Here is my code:
multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);
File f = new File("C:\\foo\\bar");
File[] attachments = f.listFiles();
//email with attachments (if any)
for(int i = 0; i < f.listFiles().length - 1; i++){
DataSource fileDataSource = new FileDataSource(attachments[i]);
messageBodyPart.setDataHandler(new DataHandler(fileDataSource));
messageBodyPart.setFileName(attachments[i].getName());
multipart.addBodyPart(messageBodyPart);
}
message.setContent(multipart);
message.setSentDate(new Date());
Transport.send(message);
You have an off-by-one error: you want the loop to be either
for (int i = 0; i < f.listFiles().length; i++){
or
for (int i = 0; i <= f.listFiles().length -1; i++){
You also have two lines that say
multipart.addBodyPart(messageBodyPart);
which is why you have the bodypart containing the first file twice.