Send Forign Charcter like Arabic letters in Emails using JavaMail Api - java

I am using Velocity Engine as template engine to send email. Email template is in .vm files and I set any variables that I want to set and send email using JavaMail api. For English, this is working all fine. But for Arabice, I don't get the letters correctly.
Note that I have set content type utf-8 in html format and also set content type in the Java code also.
<html>
<head><meta charset="utf-8"></head>...
Also I don't have the luxory of using Spring, so VelocityEngineUtils cannot be used.
VelocityEngine ve = new VelocityEngine();
ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
ve.setProperty("classpath.resource.loader.class",ClasspathResourceLoader.class.getName());
ve.init();
Template t = ve.getTemplate("email_template.vm");
VelocityContext context = new VelocityContext();
context.put("variable", "param");
StringWriter writer = new StringWriter();
t.merge(context, writer);
Following is the mail sending code. You can see that I set UTF-8 character encoding when setting text
MimeMessage message = new MimeMessage(session);
message.setSender(new InternetAddress("senderEmail#gmail.com", "Test application"));
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse("receipant#gmail.com"));
message.setSubject("Testing Subject");
message.setText(writer.toString(),"UTF-8", "html");

Template t = ve.getTemplate("email_template.vm", "UTF-8");
did the trick

Related

Embed a link in email message for file attached using JavaMail doesn't work

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.

Java Mail API - Encoding problems

I'm using Java Mail API and I'm trying to send an email through Gmail's SMTP.
How my program works:
java.util.Scanner class is used to get user input - I'm asking user for various parameters to be used in mail sending class; which does the following:
Message mailMessage = new MimeMessage(session);
mailMessage.setFrom(new InternetAddress("example#example.com"));
mailMessage.setRecipients(Message.RecipientType.TO,InternetAddress.parse(mail.getTo()));
mailMessage.setSubject(mail.getSubject());
mailMessage.setText(mail.getMessage());
Transport.send(mailMessage);
Everything works as long as I use ASCII symbols/ chars. But whenever I want to use "country-specific" characters - like [õäöü] - I get bunch of weird-looking symbols...
Techniques I've used so far(which don't work for me):
setHeader("Content-Type", "text/plain; charset=UTF-8");
setHeader("Content-Encoding","ISO-8859-9");
setContent(message, "text/plain; charset=iso-8859-2");
Note: everything is displayed correctly inside an IDE when System.out.println() is performed to display the message to be sent.
EDIT: e.x. when sent message body is [õäöü]
It's displayed [ä„”?] in Gmail.
EDIT: When mailMessage.setText(MimeUtility.encodeText(mail.getMessage(), "UTF-8", "Q")); is used, then the output in Gmail is following:
"=?UTF-8?Q?=C3=A4=E2=80=9E=E2=80=9D=EF=BF=BD;=0D=0A?="
ANOTHER EDIT: Interestingly, when I do: mailMessage.setText(strVar + "õäöü", "ISO-8859-1");
It actually appends "õäöü" nicely in my email (but the first part[strVar] of the string is still full of ?'s and []'s).
MimeMessage message = new MimeMessage(session);
message.setSubject(subject, "UTF-8");
message.setText(body, "UTF-8");
So one has to set the character encoding for both, body and subject.
Addendum because of comment of #bartac
For the corresponding MimeBodyPart do a setHeader("Content-Type", "text/plain; charset=UTF-8").
You should use setText(String text, String charset) or setText(String text, String charset, String subtype) to set the text body with a specific encoding.
MimeUtility.encodeText() is not meant for body text, but only for encoded text in headers (and then only for headers set with setHeader or addHeader).
Basically, my code works just fine, as its supposed to. It was the cmd, that could not handle non-ascii letters. I used a bat file to access a jar. I think I'm just going to make a little GUI then... Thanks everyone for answering.
The following worked for me:
MimeMessage message = ...
message.setSubject(subject, "UTF-8");
message.setContent(body, "text/plain; charset=UTF-8");
Where subject and body are regular String objects with no special treatment (code and user interface use UTF-8).
1- Consider you want to send an email with this string in the body:
"Olá João!"
2 - As the code is running in the GAE server, this string is interpreted with the default ASCII encoding. To send this email with the correct accented characters, define the String as:
String body = "Ol\u00e1 Jo\u00e3o!";
The special characters are manually defined with its UTF-8 codes. Search the codes you need in the table http://www.utf8-chartable.de/
3- Convert the string encoding to UTF-8. All the codes manually typed will be now correctly interpreted:
Session session = Session.getDefaultInstance(props);
MimeMessage message = new MimeMessage(session);
String encodedSubject = new String (subject.getBytes("UTF-8"),"UTF-8");
String encodedBody = new String (body.getBytes("UTF-8"),"UTF-8");
message.setSubject(encodedSubject, "UTF-8");
message.setText(encodedBody, "UTF-8");
JavaMailSenderImpl emailSender = new JavaMailSenderImpl();
mailSender.setHost("...");
MimeMessage message = emailSender.createMimeMessage();
message.setSubject("...", "UTF-8");
message.setText("...", "UTF-8");
MimeMessageHelper helper = new MimeMessageHelper(message, "UTF-8");
helper.setFrom(from);
helper.setTo(to);
emailSender.send(message);
In case if you use HTML messages, try this:
Message message = new MimeMessage(session);
message.setContent(htmlText, "text/html; charset=UTF-8");
the following charset working to me: charset=ISO-8859-1, example:
mail.setContent(testMail.getTexto(), "text/plain; charset=ISO-8859-1");

Embedding inline image in email and referring it thru cid?

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.

Sending an html email with an image in GAE

When I send an e-mail currently from within GAE I receive the email with a Content-Transfer-Encoding of quoted-printable. I am looking to set this to base64. The quoted-printable would be find except the image is not displayed when I receive the email. As it is right now my html which looks like this:
String base64StringImg = Base64.encode(my byte array);
StringBuilder htmlBody = new StringBuilder();
htmlBody.append("<html>");
htmlBody.append("<body>");
htmlBody.append("<img src='data:image/png;base64,");
htmlBody.append(base64StringImg);
htmlBody.append("'/>");
htmlBody.append("<br/><br/>");
htmlBody.append("Hello " + name);
htmlBody.append("</body>");
htmlBody.append("</html>");
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(fromUser));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(recipient));
message.setSubject(subject);
Multipart mp = new MimeMultipart();
BodyPart htmlPart = new MimeBodyPart();
htmlPart.setContent(htmlBody.toString(), "text/html; charset=UTF-8");
mp.addBodyPart(htmlPart);
message.setContent(mp);
Transport.send(message);
How can I send an html e-mail with an image in GAE? I have read the following two bug/feature requests which make it clear there are limitations.
http://code.google.com/p/googleappengine/issues/detail?id=198
http://code.google.com/p/googleappengine/issues/detail?id=965
HTML embedded images seem to be poorly supported in email clients: http://www.campaignmonitor.com/blog/post/1761/embedding-images-in-email/
What is supported are images HTML images attached to email: http://www.campaignmonitor.com/blog/post/1759/embedding-images-revisited/
However, as you noted with the link to the issue, the second option is poorly supported in GAE. What you could try is create by hand the mail content shown in second link.

How to send html email to outlook from Java

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

Categories