Java 邮件:设置中文编码
Java Mail: Setting Chinese Encoding
我通过gmail给自己发了一封中文邮件,我成功收到了下面的headers
当我通过javax.mail发送中文邮件时,在我的邮件浏览器中显示如下
失败邮件的header如下:
我的代码如下:
public boolean send() throws TestReportingException, MessagingException
{
try
{
String encodingOptions = "text/plain; charset=UTF-8";
Authenticator authenticator = new Authenticator()
{
// override the getPasswordAuthentication method
protected PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication(username, password);
}
};
// Create the mail session
Session session = Session.getInstance(maileProperties, authenticator);
MimeMessage mimeMessage = new MimeMessage(session);
mimeMessage.setHeader("Content-Type", encodingOptions);
// Set From: header field of the header.
mimeMessage.setFrom(new InternetAddress(from, fromName));
// Set To: header field of the header.
for (String s : toList)
{
if (null == s)
{
throw new TestReportingException("Email address is null");
}
mimeMessage.addRecipients(Message.RecipientType.TO, InternetAddress.parse(s));
}
for (String s : ccList)
{
mimeMessage.addRecipients(Message.RecipientType.CC, InternetAddress.parse(s));
}
// Set Subject: header field
mimeMessage.setSubject(subject,"UTF-8");
// Create the message part
//MimeBodyPart messageBodyPart = new MimeBodyPart();
// messageBodyPart.setContent(message, encodingOptions);
// Create the message part
MimeBodyPart messageBodyPart = new MimeBodyPart();
mimeMessage.setHeader("Content-Type", encodingOptions);
// Now set the actual message
messageBodyPart.setText(message, "utf-8", "plain");
// Now set the actual message
//messageBodyPart.setText(message, "utf-8", "html");
Multipart multipart = new MimeMultipart();
// Set text message part
multipart.addBodyPart(messageBodyPart);
// Part two is attachment
if (null != attachmentSource)
{
messageBodyPart = new MimeBodyPart();
messageBodyPart.setDataHandler(new DataHandler(attachmentSource));
messageBodyPart.setFileName(attachmentSource.getName());
multipart.addBodyPart(messageBodyPart);
}
// Send the complete message parts
mimeMessage.setContent(multipart);
// Send message
//Transport.send(mimeMessage);
SSm.getLogger().debug("Subject: "+mimeMessage.getSubject());
Transport.send(mimeMessage);
SSm.getLogger().info("\n\nSent message successfully....");
clear();
return true;
}
catch (MessagingException mex)
{
SSm.getLogger().error(mex.getMessage());
throw mex;
}
catch (Exception e)
{
SSm.getLogger().error(e.getMessage(), e);
throw new TestReportingException(e.getMessage(), e);
}
}
属性是:
- 主机=smtp.gmail.com
- mail.smtp.auth=真
- mail.smtp.starttls.enable=真mail.smtp.host=smtp.gmail.com
- mail.smtp.port=587 mail.mime.charset=UTF-8
注意事项:
文本在发送前没有损坏。
message.getSubject() 打印出干净的中文文本
我猜我编码的方式有问题
编辑
调试输出如下:
DEBUG: setDebug: JavaMail version 1.5.5
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
DEBUG SMTP: need username and password for authentication
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host "smtp.gmail.com", port 587, isSSL false
220 smtp.gmail.com ESMTP s20sm18171725pfg.11 - gsmtp
DEBUG SMTP: connected to host "smtp.gmail.com", port: 587
>
EHLO jake-yoga3.hitronhub.home
250-smtp.gmail.com at your service, [96.49.181.179]
250-SIZE 35882577
250-8BITMIME
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-CHUNKING
250 SMTPUTF8
DEBUG SMTP: Found extension "SIZE", arg "35882577"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "STARTTLS", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "CHUNKING", arg ""
DEBUG SMTP: Found extension "SMTPUTF8", arg ""
STARTTLS
220 2.0.0 Ready to start TLS
EHLO jake-yoga3.hitronhub.home
250-smtp.gmail.com at your service, [96.49.181.179]
250-SIZE 35882577
250-8BITMIME
250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-CHUNKING
250 SMTPUTF8
DEBUG SMTP: Found extension "SIZE", arg "35882577"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "AUTH", arg "LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH"
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "CHUNKING", arg ""
DEBUG SMTP: Found extension "SMTPUTF8", arg ""
DEBUG SMTP: Attempt to authenticate using mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM XOAUTH2
DEBUG SMTP: Using mechanism LOGIN
DEBUG SMTP: AUTH LOGIN command trace suppressed
DEBUG SMTP: AUTH LOGIN succeeded
DEBUG SMTP: use8bit false
MAIL FROM:
250 2.1.0 OK s20sm18171725pfg.11 - gsmtp
RCPT TO:
250 2.1.5 OK s20sm18171725pfg.11 - gsmtp
DEBUG SMTP: Verified Addresses
DEBUG SMTP: JSTONE@I-KODA.COM
DATA
354 Go ahead s20sm18171725pfg.11 - gsmtp
From: iKoda Report
To: JSTONE@I-KODA.COM
Message-ID: <1926337998.1.1488002481716@jake-yoga3>
Subject: =?UTF-8?B?QnZ4Y2Igw6TCuMKtIMOkwrjCrSDDpMK4wq0gw6TCuMKtIMOkwrjCrQ==?=
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="----=_Part_0_1855484302.1488002481637"
>
------=_Part_0_1855484302.1488002481637
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: base64
>
RGVhciBaeGN2LA0KDQpCdnhjYiDDpMK4wq0gw6TCuMKtIMOkwrjCrSDDpMK4wq0gw6TCuMKtw6TC
uMKtIMOkwrjCrSDDpMK4wq0gw6TCuMKtIMOkwrjCrWh0dHBzOi8vd3d3Lmkta29kYS5jb20vZGVs
aXZlcnkvZHNmcj91ZnQ9MTAxMjc3MCZjPTEwMTI3NjTDpMK4wq0gw6TCuMKtIMOkwrjCrSDDpMK4
wq0gw6TCuMKt
------=_Part_0_1855484302.1488002481637--
.
250 2.0.0 OK 1488002489 s20sm18171725pfg.11 - gsmtp
DEBUG SMTP: message successfully delivered to mail server
QUIT
221 2.0.0 closing connection s20sm18171725pfg.11 - gsmtp
[INFO] "jake.app" com.ikoda.service.utilities.EmailOut.send(EmailOut.java:256) 01:27:
>
Sent message successfully....
>
我找到问题了。
问题不在电子邮件 class 中,仅与 javamail 无关。
(所以上面的代码是正确的)
问题在于从我的控制器中 Spring 的 MessageBundle 的热连线实例中提取文本。
我错误地使用了以下代码,以便我的日志记录 class 可以记录从消息包中提取的字符串。
byte[] barray =messageSource.getMessage(code, null, LocaleContextHolder.getLocale()).getBytes(Charset.forName("UTF-8"));
String s = new String(barray);
Log4j 可以读取主题和消息中的字符串(由 StringBuilder 构建),这让我相信字符串是正确的 UTF-8。但是,javax.mail在传输中出现乱码。
我应该做的是:
messageSource.getMessage(code, null, LocaleContextHolder.getLocale())
现在我的记录器只收到 ???,但电子邮件发送正常。
所以,保持简单愚蠢。
我通过gmail给自己发了一封中文邮件,我成功收到了下面的headers
当我通过javax.mail发送中文邮件时,在我的邮件浏览器中显示如下
失败邮件的header如下:
我的代码如下:
public boolean send() throws TestReportingException, MessagingException
{
try
{
String encodingOptions = "text/plain; charset=UTF-8";
Authenticator authenticator = new Authenticator()
{
// override the getPasswordAuthentication method
protected PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication(username, password);
}
};
// Create the mail session
Session session = Session.getInstance(maileProperties, authenticator);
MimeMessage mimeMessage = new MimeMessage(session);
mimeMessage.setHeader("Content-Type", encodingOptions);
// Set From: header field of the header.
mimeMessage.setFrom(new InternetAddress(from, fromName));
// Set To: header field of the header.
for (String s : toList)
{
if (null == s)
{
throw new TestReportingException("Email address is null");
}
mimeMessage.addRecipients(Message.RecipientType.TO, InternetAddress.parse(s));
}
for (String s : ccList)
{
mimeMessage.addRecipients(Message.RecipientType.CC, InternetAddress.parse(s));
}
// Set Subject: header field
mimeMessage.setSubject(subject,"UTF-8");
// Create the message part
//MimeBodyPart messageBodyPart = new MimeBodyPart();
// messageBodyPart.setContent(message, encodingOptions);
// Create the message part
MimeBodyPart messageBodyPart = new MimeBodyPart();
mimeMessage.setHeader("Content-Type", encodingOptions);
// Now set the actual message
messageBodyPart.setText(message, "utf-8", "plain");
// Now set the actual message
//messageBodyPart.setText(message, "utf-8", "html");
Multipart multipart = new MimeMultipart();
// Set text message part
multipart.addBodyPart(messageBodyPart);
// Part two is attachment
if (null != attachmentSource)
{
messageBodyPart = new MimeBodyPart();
messageBodyPart.setDataHandler(new DataHandler(attachmentSource));
messageBodyPart.setFileName(attachmentSource.getName());
multipart.addBodyPart(messageBodyPart);
}
// Send the complete message parts
mimeMessage.setContent(multipart);
// Send message
//Transport.send(mimeMessage);
SSm.getLogger().debug("Subject: "+mimeMessage.getSubject());
Transport.send(mimeMessage);
SSm.getLogger().info("\n\nSent message successfully....");
clear();
return true;
}
catch (MessagingException mex)
{
SSm.getLogger().error(mex.getMessage());
throw mex;
}
catch (Exception e)
{
SSm.getLogger().error(e.getMessage(), e);
throw new TestReportingException(e.getMessage(), e);
}
}
属性是:
- 主机=smtp.gmail.com
- mail.smtp.auth=真
- mail.smtp.starttls.enable=真mail.smtp.host=smtp.gmail.com
- mail.smtp.port=587 mail.mime.charset=UTF-8
注意事项: 文本在发送前没有损坏。 message.getSubject() 打印出干净的中文文本 我猜我编码的方式有问题
编辑
调试输出如下:
DEBUG: setDebug: JavaMail version 1.5.5
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
DEBUG SMTP: need username and password for authentication
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host "smtp.gmail.com", port 587, isSSL false
220 smtp.gmail.com ESMTP s20sm18171725pfg.11 - gsmtp
DEBUG SMTP: connected to host "smtp.gmail.com", port: 587
>
EHLO jake-yoga3.hitronhub.home
250-smtp.gmail.com at your service, [96.49.181.179]
250-SIZE 35882577
250-8BITMIME
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-CHUNKING
250 SMTPUTF8
DEBUG SMTP: Found extension "SIZE", arg "35882577"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "STARTTLS", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "CHUNKING", arg ""
DEBUG SMTP: Found extension "SMTPUTF8", arg ""
STARTTLS
220 2.0.0 Ready to start TLS
EHLO jake-yoga3.hitronhub.home
250-smtp.gmail.com at your service, [96.49.181.179]
250-SIZE 35882577
250-8BITMIME
250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-CHUNKING
250 SMTPUTF8
DEBUG SMTP: Found extension "SIZE", arg "35882577"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "AUTH", arg "LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH"
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "CHUNKING", arg ""
DEBUG SMTP: Found extension "SMTPUTF8", arg ""
DEBUG SMTP: Attempt to authenticate using mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM XOAUTH2
DEBUG SMTP: Using mechanism LOGIN
DEBUG SMTP: AUTH LOGIN command trace suppressed
DEBUG SMTP: AUTH LOGIN succeeded
DEBUG SMTP: use8bit false
MAIL FROM:
250 2.1.0 OK s20sm18171725pfg.11 - gsmtp
RCPT TO:
250 2.1.5 OK s20sm18171725pfg.11 - gsmtp
DEBUG SMTP: Verified Addresses
DEBUG SMTP: JSTONE@I-KODA.COM
DATA
354 Go ahead s20sm18171725pfg.11 - gsmtp
From: iKoda Report
To: JSTONE@I-KODA.COM
Message-ID: <1926337998.1.1488002481716@jake-yoga3>
Subject: =?UTF-8?B?QnZ4Y2Igw6TCuMKtIMOkwrjCrSDDpMK4wq0gw6TCuMKtIMOkwrjCrQ==?=
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="----=_Part_0_1855484302.1488002481637"
>
------=_Part_0_1855484302.1488002481637
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: base64
>
RGVhciBaeGN2LA0KDQpCdnhjYiDDpMK4wq0gw6TCuMKtIMOkwrjCrSDDpMK4wq0gw6TCuMKtw6TC
uMKtIMOkwrjCrSDDpMK4wq0gw6TCuMKtIMOkwrjCrWh0dHBzOi8vd3d3Lmkta29kYS5jb20vZGVs
aXZlcnkvZHNmcj91ZnQ9MTAxMjc3MCZjPTEwMTI3NjTDpMK4wq0gw6TCuMKtIMOkwrjCrSDDpMK4
wq0gw6TCuMKt
------=_Part_0_1855484302.1488002481637--
.
250 2.0.0 OK 1488002489 s20sm18171725pfg.11 - gsmtp
DEBUG SMTP: message successfully delivered to mail server
QUIT
221 2.0.0 closing connection s20sm18171725pfg.11 - gsmtp
[INFO] "jake.app" com.ikoda.service.utilities.EmailOut.send(EmailOut.java:256) 01:27:
>
Sent message successfully....
>
我找到问题了。 问题不在电子邮件 class 中,仅与 javamail 无关。 (所以上面的代码是正确的)
问题在于从我的控制器中 Spring 的 MessageBundle 的热连线实例中提取文本。
我错误地使用了以下代码,以便我的日志记录 class 可以记录从消息包中提取的字符串。
byte[] barray =messageSource.getMessage(code, null, LocaleContextHolder.getLocale()).getBytes(Charset.forName("UTF-8"));
String s = new String(barray);
Log4j 可以读取主题和消息中的字符串(由 StringBuilder 构建),这让我相信字符串是正确的 UTF-8。但是,javax.mail在传输中出现乱码。
我应该做的是:
messageSource.getMessage(code, null, LocaleContextHolder.getLocale())
现在我的记录器只收到 ???,但电子邮件发送正常。
所以,保持简单愚蠢。