I'm trying to embed a link in email for a file attached in email message using JavaMail APi like here.
This is my code:
MimeMultipart multipart = new MimeMultipart("related");
BodyPart messageBodyPart = new MimeBodyPart();
String attachment = "/path/test.pdf";
File fAtachh = new File(attachment);
String htmlText = "<a href='cid:file'>test.pdf</a>";
messageBodyPart.setContent(htmlText, "text/html");
multipart.addBodyPart(messageBodyPart);
MimeBodyPart messageBodyPartAttach = new MimeBodyPart();
try {
messageBodyPartAttach.attachFile(fAtachh);
} catch (IOException e) {
logger.info("Exception" + e.getMessage());
}
messageBodyPartAttach.setContentID("<file>");
multipart.addBodyPart(messageBodyPartAttach);
message.setContent(multipart);
The problem is that link doesn't work:
ErrorLink
If change the last code by:
MimeMultipart multipart = new MimeMultipart("related");
MimeBodyPart messageBodyPart = new MimeBodyPart();
String attachment = "/path/test.pdf";
String htmlText = "<a href='cid:file'>test.pdf</a>";
messageBodyPart.setContent(htmlText, "text/html");
multipart.addBodyPart(messageBodyPart);
MimeBodyPart messageBodyPartAttach = new MimeBodyPart();
DataSource fds = new FileDataSource
(attachment);
messageBodyPartAttach.setDataHandler(new DataHandler(fds));
messageBodyPartAttach.setHeader("Content-ID","<file>");
multipart.addBodyPart(messageBodyPartAttach);
message.setContent(multipart);
The link Works but the file name and extension are wrong:
WrongFileName
I've tried to change the file name by method:
messageBodyPartAttach.setFileName("test.pdf");
but if I set the file name, the link doesn´t work like in the first code.
Any suggestion?
Thanks!
The attachFile method sets the filename and sets the Content-Disposition to ATTACHMENT. In a multipart/related message you probably don't want those set, although it likely depends on what mail reader you're using to display the message.
There should be no functional different between using the setContentID method and using the setHeader method with "Content-ID".
Normally multipart/related messages are used to allow the html part to reference an image part also included in the message, and displayed along with the html part. Probably no mail readers are going to display a pdf file inline with the html.
Maybe the question to ask is, what exactly are you trying to accomplish?
If you just want the pdf file to appear as an attachment with a correct filename that the user can then click on to save or view, you should use the (default) multipart/mixed instead of multipart/related. I'm not sure there's a good way to embed the link to the attached file in the html text. If you're able to create such a message with some other mailer, you can examine the structure of that message and replicate it using JavaMail.
I'm having an issue with sending attachments via email in java using the java mail (1.4.6). It seems that when I attach a document of any sort and send it, the recipient gets the file in plain text format in the body. Rather than, you guessed it, sending the whole file like you would expect and the body not interfered with.
Code
try
{
// Create a message
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(username));
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse(Compose.to));
message.setSubject(Compose.subject);
//message.setText(Compose.body);
//If there are no CC's then skip it. This if seemed to decrease send time.
if(Compose.cc != null)
{
message.setRecipients(Message.RecipientType.CC, InternetAddress.parse(Compose.cc));
message.saveChanges();
}
else
message.saveChanges();
/*
* For adding the attached file to the email. This time the if
* statement is used to stop the email attachment process if there
* is none. Other wise due to the way I've set it up it'll try to
* send file path and file name as null, and we fail an otherwise valid email.
*/
if(Compose.filename != null)
{
String file = Compose.filepath;
String fileName = Compose.filename;
Multipart multipart = new MimeMultipart();
BodyPart messageBodyPart = new MimeBodyPart();
DataSource source = new FileDataSource(file);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(fileName);
multipart.addBodyPart(messageBodyPart);
BodyPart messageBodyPart2 = new MimeBodyPart();
messageBodyPart2.setText(Compose.body);
multipart.addBodyPart(messageBodyPart2);
message.setContent(multipart);
}
else
{
message.setText(Compose.body);
message.saveChanges();
}
//Send the message by javax.mail.Transport .
Transport tr = session.getTransport("smtp"); // Get Transport object from session
tr.connect(smtphost, username, password); // We need to connect
tr.sendMessage(message, message.getAllRecipients()); // Send message
//Notify the user everything functioned fine.
JOptionPane.showMessageDialog(null, "Your mail has been sent.");
}
Thinking over this I remembered how FileDataSource() is an overloaded statement taking a string or a file type as a parameter, trying both I got the same result but I will experiment more with the the file type now.
EDIT: After more testing I noticed that sometimes the file will not appear along with whatever was in the body at the time of sending.
For each part you have to set disposition to Part.INLINE for the body and Part.ATTACHMENT for the attachment. The attachFile methods will do that for you. Avoid JavaMail 1.4.6 in favor of the latest release or at least use JavaMail 1.4.7 which contains fixes for known issues with JavaMail 1.4.6.
You're setting the attachment as the first body part. It needs to be the second body part.
Also, consider upgrading to JavaMail 1.5.4 and using the MimeBodyPart.attachFile method to attach the file.
i am sending the inline image with email with mime message. Here is the brief code for the same. This is working fine. My
question is i am not setting the MimeMessage content-type as multipart/related (Also not setting
multipart subtype as related)still my code is working fine and iam able to get the inline image at expected postion.
Should i really care about setting the Content-Type as multipart/related when i am referring the image part with cid
or server takes care of that?
MimeMessage msg = new MimeMessage(mailSession);
MimeMultipart mpart = new MimeMultipart();
MimeBodyPart bp = new MimeBodyPart();
bp.setText("plain text and here is html image refering image part <img src="cid:Unique-ContentId" />", CHARSET_UTF_8, MESSAGE_HTML_CONTENT_TYPE);
// add message body
mpart.addBodyPart(bp);
// adding inline image part
MimeBodyPart bodyPart1 = new MimeBodyPart();
bodyPart1.setFileName("inline image");
file1 = new File("image1");
DataSource source1 = new FileDataSource(file);
bodyPart1.setDataHandler(new DataHandler(source));
bodyPart1.setDisposition(MimeBodyPart.INLINE);
bodyPart1.setHeader("Content-ID", "Unique-ContentId");
bodyPart1.setHeader("Content-Type", "image/jpeg");
mpart.addBodyPart(bodyPart1);
// At last setting multipart In MimeMessage
msg.setContent(mpart);
Just for information my email client can be outlook,lotusnotes,yahoo,gmail,thunderbird
That's what we call "luck". :-)
Apparently the email clients you're using are being very generous in the way they interpret the message you're sending. There's nothing in the email specs that suggest they should interpret such messages in this way.
I have been trying to get a solution but I am not able to. Here is the whole thing. I wrote the following code
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
message.setSubject(subject);
message.setSentDate(new Date());
MimeBodyPart messagePart = new MimeBodyPart();
messagePart.setContent(messageContent, "text/html");
Multipart multipart = new MimeMultipart("mixed");
multipart.addBodyPart(messagePart);
MimeBodyPart attachmentPart = new MimeBodyPart();
DataSource source = new ByteArrayDataSource(attachment.getBytes(), "text/plain");
attachmentPart.setDataHandler(new DataHandler(source));
attachmentPart.setFileName(attachmentFileName);
multipart.addBodyPart(attachmentPart);
message.setContent(multipart);
try {
Transport.send(message);
} catch (Exception e) {
e.printStackTrace();
}
The code is pretty much self explanatory. messagePart is the mail and attachmentPart is the attachment. But messagePart here is not plain text. It is HTML. So the problem is if I run this code mail is sent successfully but the attachment does not come attached to the mail. So my question boils down to this. Is it possible to send html content and attach something to a mail at the same time. I am stuck here. Could anyone help please.
I don't see anything obviously wrong with your code.
How are you determining that the message has no attachment?
You can see exactly what JavaMail would send by adding "message.writeTo(System.out);" just before you call Transport.send.
What version of JavaMail are you using? What mail server are you using? Some mail servers (I'm looking at you, Exchange) will reformat the message to what they think it should be, even if it's different than what you intended.
If you are running on Google App Engine and you add a dummy text part it works great. I have no idea why the dummy text part makes it work, but I was having the exact same problem and adding a dummy text part worked for me too.
You want to add
attachmentPart.setDisposition(Part.ATTACHMENT);
Part.ATTACHMENT means the part should be showed as an attachment.
Part.INLINE means you want to show the attachment as part of the message.
I'm trying to send an email in html format using JavaMail but it always seems to only display as a text email in Outlook.
Here is my code:
try
{
Properties props = System.getProperties();
props.put("mail.smtp.host", mailserver);
props.put("mail.smtp.from", fromEmail);
props.put("mail.smtp.auth", authentication);
props.put("mail.smtp.port", port);
Session session = Session.getDefaultInstance(props, null);
// -- Create a new message --
MimeMessage message = new MimeMessage(session);
// -- Set the FROM and TO fields --
message.setFrom(new InternetAddress(fromEmail, displayName));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to, false));
MimeMultipart content = new MimeMultipart();
MimeBodyPart text = new MimeBodyPart();
MimeBodyPart html = new MimeBodyPart();
text.setText(textBody);
text.setHeader("MIME-Version" , "1.0" );
text.setHeader("Content-Type" , text.getContentType() );
html.setContent(htmlBody, "text/html");
html.setHeader("MIME-Version" , "1.0" );
html.setHeader("Content-Type" , html.getContentType() );
content.addBodyPart(text);
content.addBodyPart(html);
message.setContent( content );
message.setHeader("MIME-Version" , "1.0" );
message.setHeader("Content-Type" , content.getContentType() );
message.setHeader("X-Mailer", "My own custom mailer");
// -- Set the subject --
message.setSubject(subject);
// -- Set some other header information --
message.setSentDate(new Date());
// INFO: only SMTP protocol is supported for now...
Transport transport = session.getTransport("smtp");
transport.connect(mailserver, username, password);
message.saveChanges();
// -- Send the message --
transport.sendMessage(message, message.getAllRecipients());
transport.close();
return true;
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
throw e;
}
Any ideas why the html version of the email won't display in Outlook?
After a lot of investigation, I've been able to make some significant progress.
Firstly, instead of using JavaMail directly, I recommend using the Jakarta Commons Email library. This really simplifies the issue a lot!
The code is now:
HtmlEmail email = new HtmlEmail();
email.setHostName(mailserver);
email.setAuthentication(username, password);
email.setSmtpPort(port);
email.setFrom(fromEmail);
email.addTo(to);
email.setSubject(subject);
email.setTextMsg(textBody);
email.setHtmlMsg(htmlBody);
email.setDebug(true);
email.send();
Talk about simple.
However, there is still an issue. The html version of the email works great in Gmail, Hotmail, etc. But it still won't correctly display in Outlook. It always wants to display the text version and I'm not sure why. I suspect it's a setting in Outlook, but I can't find it...
In addition to removing the html.setHeader("Content-Type", html.getContentType())
call as suggest already, I'd replace the line:
MimeMultipart content = new MimeMultipart();
…with:
MimeMultipart content = new MimeMultiPart("alternative");
…and removing the line:
message.setHeader("Content-Type" , content.getContentType() );
The default MimeMultiPart constructor could be causing problems with a "multipart/mixed" content-type.
When using multipart/alternative, the alternatives are ordered by how faithful they are to the original, with the best rendition last. However, clients usually give users an option to display plain text, even when HTML is present. Are you sure that this option is not enabled in Outlook? How do other user agents, like Thunderbird, or GMail, treat your messages?
Also, ensure that the HTML is well-formed. I'd validate the HTML content with the W3 validation service, and possibly save it into a file and view it with different versions of IE too. Maybe there's a flaw there causing Outlook to fall back to plain text.
html.setContent(htmlBody, "text/html");
html.setHeader("MIME-Version" , "1.0" );
html.setHeader("Content-Type" , html.getContentType() );
setContent and setHeader("Content-Type", String) do the same thing - is it possible that html.getContentType() is returning something other than text/html?
Expanding based on comment and #PhilLho & #erickson's answer (geez, I must type slowly), use:
MimeMultipart content = new MimeMultipart("alternative")
Change this To:
message.setContent(new String(sBuffer.toString().getBytes(), "iso-8859-1"), "text/html; charset=\"iso-8859-1\"");
The content char set need to be set, I don't see why the content itself.
Should rather be:
message.setContent(sBuffer.toString(), "text/html;charset=iso-8859-1");
I used the following code:
mimeBodyPart1.setDataHandler(new DataHandler(new ByteArrayDataSource(messageBody, "text/html; charset=utf-8")));
multiPart.addBodyPart(mimeBodyPart1);
message.setContent(multiPart, "text/html; charset=utf-8");
Now, Outlook displays in html format.
You should look at the source of the received message: is the Content-Type of the message multipart/alternative?
message.setContent(new String(sBuffer.toString().getBytes(), "iso-8859-1"), "text/html; charset=iso-8859-1");
Should solve your problem (removed \" characters).
workaroung solution solved outlook 2003: This message uses a character set that is not supported by the Internet Service. doesn't display correctly.
It could be due to the encoding. Most html pages use iso-8859-1 not cp-1252 try changing
For example, your code is:
message.setContent(sBuffer.toString(), "text/html");
Change this to:
message.setContent(new String(sBuffer.toString().getBytes(), "iso-8859-1"), "text/html; charset=\"iso-8859-1\"");
This throws a new checked exception : java.io.UnsupportedEncodingException so you need to declare it to be thrown or catch it.
iso-8859-1 is supported so, the exception will never be thrown unless something gets corrupted with your rt.jar.
Regards,
Javeed
javeed.mca#gmail.com