12

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("[email protected]"));
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).

6
  • How do you set strVar?, and what if you assign strVar immediately before that mailMessate.setText(..)? Maybe the content you receive from the scanner is not the same as the string that does work. Commented Dec 21, 2012 at 8:47
  • I have changed my code a little bit to allow me to send HTML, so my send method is: message.setContent("<h5>[õäöü]</h5><h1>" + strVar + "</h1>", "text/html"); When I get an mail HTML is parsed correctly, so is "[õäöü]", but strVar seems to "come" incorrectly. I have a class Input and get() method inside it: public String get(){ /* Scanner declaration here */ return scanner.nextLine(); } And in second class MailSender I initialize strVar like that: ` /* Input class declaration */ String strVar = input.get(); ` // Sorry, hard to write code in here :) Commented Dec 21, 2012 at 11:33
  • Could you check which actual characters are in the string (and how it compares to the characters in the case that does work)? Commented Dec 21, 2012 at 11:37
  • Sure, you can see the output here: link Output is kind of weird, I run my program in both IDE's (IntelliJ and Netbeans). I used their own console for input [Scanner(System.in)]. Intellij seems to output everything correctly, but Netbeans incorrectly. First line(CMD) on picture. It's actually a jar made from Netbeans. It gets subject line right (Netbeans didn't) but body is ok (same in netbeans IDE's console). "Häid Jõule" means Merry Christmas in Estonian btw :) Commented Dec 21, 2012 at 11:59
  • Then the problem is probably not with JavaMail, but with the encoding of the consoles, not sure how to change that though. Commented Dec 21, 2012 at 12:23

8 Answers 8

14
    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").

Sign up to request clarification or add additional context in comments.

4 Comments

Using setText will also set the Content-Type header (and if you look through the code you will see that existing Content-Type and Content-Transfer-Encoding headers are removed after setting any content using setText or setContent)
@MarkRotteveel thanks, I will remove the redundant setHeader("Content-Type", "text/plain; charset=UTF-8").
message.setText(body, "text/plain; charset=UTF-8") or similar haven't worked for me in Windows 10 default Mail application (and sometimes in Outlook) for certain slavic letters. I solved it by using MimeBodyPart and setting setHeader("Content-Type", "text/plain; charset=UTF-8") on it. As for the subject, message.setSubject(subject, "UTF-8") worked perfectly for slavic characters (without it, even gmail didn't recognize 'č' character).
@bartac I have added your solution. Maybe the difference between rich (with a mime part for the plain text) and plain messages.
5

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

1 Comment

I used this: mailMessage.setText("input from Scanner here", "ISO-8859-1"); But nothing changed... What else might be the problem?
2

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.

1 Comment

Hi all, i have same problem with french characters, i have tried this code: MimeMessage message = new MimeMessage(session); message.setSubject(subject, "UTF-8"); message.setBody(body, "UTF-8"); Body is being generated correctly but subject i am not getting correctly.Can someone help me
2

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

Comments

1

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

Comments

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

Comments

0

In case if you use HTML messages, try this:

Message message = new MimeMessage(session);
message.setContent(htmlText, "text/html; charset=UTF-8");

Comments

0

the following charset working to me: charset=ISO-8859-1, example:

mail.setContent(testMail.getTexto(), "text/plain; charset=ISO-8859-1");

1 Comment

why not UTF-8 ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.