32

I'm sending an email and I'm receiving it correctly but the encoding of the subject is not correct. I'm sending "invitación" but I'm receiving "invitaci?n". The content of the message is OK.

The content of the message is coming from a transformation of a Velocity Template while the subject is set in a String variable.

I've googled around and I've seen that some people says that MimeUtility.encodeText() could solve the problem, but I have had no success with it.

How can I solve the problem? This is the code I have so far.

String subject = "Invitación";
String msgBody = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, "/vmTemplates/template.vm", "UTF-8", model);

Properties props = new Properties();
Session session = Session.getDefaultInstance(props, null);

try {
    String encodingOptions = "text/html; charset=UTF-8";
    Message msg = new MimeMessage(session);
    msg.setHeader("Content-Type", encodingOptions);
    msg.setFrom(new javax.mail.internet.InternetAddress(emailFrom));
    msg.addRecipient(Message.RecipientType.TO, new InternetAddress(emailTo));

    msg.setSubject(subject);
    msg.setContent(msgBody, encodingOptions);
    Transport.send(msg);

    } catch (AddressException e) {
        ...
    } catch (MessagingException e) {
        ...
    } 

Thanks

Javi
  • 19,387
  • 30
  • 102
  • 135

5 Answers5

44

JavaMail has perhaps a little too much abstraction, and you're falling victim to it here. When you use

Message msg = new MimeMessage(session);

you're creating a MimeMessage object but treating it as a Message object. Message has only a setSubject(String subject) method, which uses the platform default charset to encode the subject. If the platform default can't encode it, you get ? characters in the resulting header. MimeMessage, however, has a setSubject(String subject, String charset) method which will allow you to specify the charset you want to use to encode the subject. So just switch your code to

MimeMessage msg = new MimeMessage(session);
msg.setHeader("Content-Type", encodingOptions);
msg.setFrom(new javax.mail.internet.InternetAddress(emailFrom));
msg.addRecipient(Message.RecipientType.TO, new InternetAddress(emailTo));

msg.setSubject(subject, "UTF-8");

and it should work.

dkarp
  • 14,483
  • 6
  • 58
  • 65
  • The only shipped subclass of `Message` is `MimeMessage`. I'm doubting that anyone's implemented another subclass. JavaMail would be less grotty if they'd just collapsed `javax.mail` and `javax.mail.internet` -- that extra layer of abstraction just means you're constantly casting to the subclass. – dkarp Feb 05 '11 at 16:47
  • This did not resolve my problem (sending the £ symbol in the subject line) – Mark W Aug 26 '11 at 08:29
  • 1
    @Mark: You tried `msg.setSubject("\u00a3", "UTF-8")` and it didn't encode the subject properly? What was in the resulting Subject header? – dkarp Aug 26 '11 at 17:35
  • Sorry. I fixed my problem, was not related to the subect encoding - it was related to reading a file that was used to populate subject, so my subject string was incorrect before adding to message. – Mark W Sep 05 '11 at 11:37
  • @dkarp: I always thought the spelling was "Groddy" ... I stand corrected :) – mtyson Dec 04 '12 at 23:06
  • Somehow I don't see the signature with 2 params. @edyluisrey answer solved problem for me. – Schultz9999 Dec 07 '13 at 21:43
8

you can use, it works

msg.setSubject(MimeUtility.encodeText("string", "UTF-8", "Q"));
Edy Aguirre
  • 2,113
  • 20
  • 20
4

Maybe you can try: msg.setSubject(subject, "UTF8");

ksimon
  • 711
  • 11
  • 24
0

In my case the only thing which worked is changing the system locale to the one which supports desired character set. Before that I tried many different ways including the accepted answer from this thread, but none of them helped.

Alexey
  • 1,521
  • 1
  • 13
  • 24
0

I have implemented emailService in one of my project and I am using MimeMessageHelper & MimeMailMessage for the same. Please refer to code as below.

private String sendEmail() {
  MimeMessage mimeMessage = EmailSenderFactory.INSTANCE.getEmailSender().createMimeMessage();
  MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
  mimeMessageHelper.setTo("YourToEmailId");
  mimeMessageHelper.setFrom("YourFromEmailId");
  mimeMessageHelper.setBcc("YourBccEmailId");
  mimeMessageHelper.setSubject("YourEmailSubject");
  mimeMessageHelper.setText("YourEmailContent", true);
  mimeMessageHelper.addAttachment("DocumentName", new ByteArrayDataSource("Document data in byte[]", "Document Content Type"));
  MimeMailMessage mimeMailMessage = new MimeMailMessage(mimeMessageHelper);
  return EmailSenderFactory.INSTANCE.getEmailSender().send(mimeMailMessage);
}
Dharman
  • 30,962
  • 25
  • 85
  • 135