Java Mail API - Encoding problems - java

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

Related

JavaMail - Attachment filename not displaying UTF-8 characters correctly

I am trying to send mails that may contain UTF-8 characters in subject, message body and in the attachment file name.
I am able to send UTF-8 characters as a part of Subject as well as Mesage body. However when I am sending an attachment having UTF-8 characters as a attachment file name, it is not displaying it correctly.
So my question is how can I set attachement filename as UTF-8?
Here is part of my code:
MimeBodyPart pdfPart = new MimeBodyPart();
pdfPart.setDataHandler(new DataHandler(ds));
pdfPart.setFileName(filename);
mimeMultipart.addBodyPart(pdfPart);
Later edit:
I replaced
pdfPart.setFileName(filename);
with
pdfPart.setFileName(MimeUtility.encodeText(filename, "UTF-8", null));
and it is working perfectly.
Thanks all.
MIME Headers (like Subject or Content-Disposition) must be mime-encoded, if they contain non-ascii chars.
Encoding is either "quoted printable" or "base64". I recommend for quoted-printable.
See here: Java: Encode String in quoted-printable
I don't know how you send attachments. If upload through tomcat server, It could cause by value of URIEncoding in conf/server.xml

Properly set encoding to UTF-8, even then email come up with ? and �

I am using javax.mail API for sending email to my Outlook. There are chinese and french characters in my Body.
I am properly setting body as
MimeMessage.setText(body, "UTF-8");
Also in the email I am checking the Headers. They are properly coming as :
Content-type: text/plain;
charset="UTF-8"
Content-transfer-encoding: quoted-printable
The funny thing is that from the Other Machine, the email is coming up fine, but when I try it from my desktop, It doesn't encode properly.
I am also checking logs by printing the body. They are properly coming up in chinese and french.
Help needed ?
Does it is anything to do with Sendmail??
Should have worked; you only forgot to do the subject too. Especially as you checked the header. Encoding calls:
MimeMessage message = new MimeMessage(session);
message.setSubject(subject, "UTF-8");
message.setText(body, "UTF-8");
//message.setHeader("Content-Type", "text/plain; charset=UTF-8");
I think, your email settings on the desktop force the wrong encoding.
Paranoia: Check the body string, via a hard-coded u-escaped string:
message.setText("\u00e9\u00f4\u5837" + body, "UTF-8"); // éô堷

In Mimemessage how to make setContent method should also change value returned by getRawInputStream method

I have the Mimemessage object already. I tried to append some content to the existing content. Using message.getContent() method, i have content object. Then i set setContent using msg.setContent(appendContent, contenttype). Afterwards, i called msg.saveChanges() also.
Then from the same mimemessage object i tried to get Rawinputstream from that using msg.getRawInputstream() method. But this returns the oldcontent not the new one. Why?
MimeMessage msg = new MimeMessage(session,inputstream);
String contenttype = msg.getContentType(); // text/plain; charset=utf-8
String content = msg.getContent(); //oldContent
String newContent = content + "\n some new content";
msg.setContent(newContent,contenttype);
msg.saveChanges();
InputStream ins = msg.getRawInputStream(); // returns oldContent stream why???????????
What version of JavaMail are you using?
JavaMail was designed to handle reading a message from a mail server or creating a new message to send to a mail server. What you're trying to do is "edit" an existing message. There have been bugs in this area of JavaMail in previous releases, and there are probably still bugs in this area in the current release.
In this particular case, there is no "raw input stream" yet for the new content. The content isn't converted to its MIME (raw) format until you write out the message.
The primary purpose of the getRawInputStream method is to allow access to the raw data in cases where the data is incorrectly formatted and JavaMail isn't able to decode or interpret it correctly. Why are you using it in this case?

sending email with arabic content through java i

I want to send email with Arabic content through java mail ,
but every Arabic word in the message appears like ????????????? ,
how can i make the encoding to utf_8 in order to support Arabic language ???
since i use that code
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to, false));
message.setSubject(subject_a);
message.setText(messageDetails_a);
Transport.send(message);
Just add some charset-information to the methods. If subject or message-body does contain other than US-ASCII characters, the default charset will be used for encoding. Explicitly setting the charset to UTF-8 will always be safe:
String charset="UTF-8";
message.setSubject(subject_a,charset);
message.setText(messageDetails_a,charset);
You have to create a MimeMessage (and keep it as a MimeMessage) and use the setSubject(subject, "UTF-8"); method for the subject.
setContent( messageContent, "text/html; charset=utf-8" ); will handle UTF-8 in the content.
With pure text :
setText(messageContent, "UTF-8");
Resources :
UTF-8 subjects in javax.mail

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