I am writing a piece of Java code that needs to send mail to users with non-ASCII names. I have figured out how to use UTF-8 for the body, subject line, and generic headers, but I am still stuck on the recipients.
Here's what I'd like in the "To:" field: "ウィキペディアにようこそ" <foo@example.com>
. This lives (for our purposes today) in a String called recip
.
msg.addRecipients(MimeMessage.RecipientType.TO, recip)
gives"忙俾ェ▎S]" <foo@example.com>
msg.addHeader("To", MimeUtility.encodeText(recip, "utf-8", "B"))
throwsAddressException: Local address contains control or whitespace in string ``=?utf-8?B?IuOCpuOCo+OCreODmuODh+OCo+OCouOBq+OCiOOBhuOBk开发者_JAVA百科+OBnSIgPA==?= =?utf-8?B?Zm9vQGV4YW1wbGUuY29tPg==?=''
How the heck am I supposed to send this message?
Here's how I handled the other components:
- Body HTML:
msg.setText(body, "UTF-8", "html");
- Headers:
msg.addHeader(name, MimeUtility.encodeText(value, "utf-8", "B"));
- Subject:
msg.setSubject(subject, "utf-8");
Ugh, got it using a stupid hack:
/**
* Parses addresses and re-encodes them in a way that won't cause {@link MimeMessage}
* to freak out. This appears to be the only robust way of sending mail to recipients
* with non-ASCII names.
*
* @param addresses The usual comma-delimited list of email addresses.
*/
InternetAddress[] unicodifyAddresses(String addresses) throws AddressException {
InternetAddress[] recips = InternetAddress.parse(addresses, false);
for(int i=0; i<recips.length; i++) {
try {
recips[i] = new InternetAddress(recips[i].getAddress(), recips[i].getPersonal(), "utf-8");
} catch(UnsupportedEncodingException uee) {
throw new RuntimeException("utf-8 not valid encoding?", uee);
}
}
return recips;
}
I hope this is useful to somebody.
I know this is old but this might help someone else. I don't understand how that solution/hack could've done anything for the issue.
This line here would set the address for recips[0] :
InternetAddress[] recips = InternetAddress.parse(addresses, false);
and this constructor here changes nothing as the encoding applies to the personal name (which is null in this case) and not the address.
new InternetAddress(recips[i].getAddress(), recips[i].getPersonal(), "utf-8");
But something like this below would work provided the mail server can handle encoded recipients ! (which doesn't seem common at all yet....)
recip = MimeUtility.encodeText(recip, "utf-8", "B");
InternetAddress[] addressArray = InternetAddress.parse(recip , false);
msg.addRecipients(MimeMessage.RecipientType.TO, addressArray);
For those who want to convert the recipients of a mail: If you are using InternetAddress.toString()
, simply change it to InternetAddress.toUnicodeString()
.
InternetAddress.toString(message.getFrom())
= =?iso-8859-3?Q?Alican_Bal=B9k?=
InternetAddress.toUnicodeString(message.getFrom())
= "Alican Balık"
精彩评论