8

发送电子邮件的代码如下:

    MimeMessage msg = new MimeMessage(session);
    msg.setSubject("subject", "UTF-8"); // here you specify your subject encoding
    msg.setContent("yourBody", "text/plain; charset=utf-8");

    msg.setFrom("senderAddress");
    msg.addRecipient(Message.RecipientType.TO, new InternetAddress(address));
    Transport.send(msg);

我的问题是,当我在 utf-8 中编码主题时,我如何编码收件人地址,即。new InternetAddress(address)

4

2 回答 2

14

电子邮件地址应遵循 RFC822 标准

JavaMail 的 MimeMessage 使用InternetAddress

此类表示使用 RFC822 语法的 Internet 电子邮件地址。典型的地址语法格式为“user@host.domain”或“Personal Name < user@host.domain >”。

RFC822 格式说:

请注意,RFC 822 将字符库限制为ASCII。在实践中,其他字符(例如 ä 或 é)通常在用于注释目的(和注释)的带引号的字符串中工作,但它们不能用于正确的地址中。

地址的个人名称支持不同的字符集

InternetAddress 使用个人名称:

如果名称包含非 US-ASCII 字符,则名称将根据 RFC 2047 使用指定的字符集进行编码。如果名称仅包含 US-ASCII 字符,则不进行编码并按原样使用名称。

要为编码设置字符集,有一个InternetAddress#constructor。查看来源:

public InternetAddress(String address, String personal, String charset)
        throws UnsupportedEncodingException {
    this.address = address;
    setPersonal(personal, charset);
}

它只是调用setPersonal(..),因此选择最方便的方式。

要查找字符集,请使用Charset.forName()

于 2012-05-31T09:40:16.633 回答
3

我这样做,其中 addressString 是带有 NLS 字符的电子邮件地址:

InternetAddress address = new InternetAddress(addressString);
String personal = address.getPersonal();
if(personal != null) {
  address.setPersonal(personal, "utf-8");
}

getPersonal()如果有原始个人姓名,则获取原始个人姓名,因为如果您使用单个字符串或使用构造 InternetAddress InternetAddress.parse(),您将不会在单独的字符串中包含个人姓名部分:

公共 java.lang.String getPersonal()

获取个人姓名。如果名称按照 RFC 2047 进行编码,则会对其进行解码并转换为 Unicode。如果解码或转换失败,则按原样返回原始数据。

然后setPersonal()再次设置字符串,但这次告诉InternetAddress要对其进行编码:

公共无效 setPersonal(java.lang.String 名称,java.lang.String 字符集)

设置个人姓名。如果名称包含非 US-ASCII 字符,则名称将根据 RFC 2047 使用指定的字符集进行编码。如果名称仅包含 US-ASCII 字符,则不进行编码并按原样使用名称。

于 2014-03-12T21:38:56.347 回答