6、Common Mail乱码问题
以下是引用片段: common mail是一个小而方便的mail包,他实现了对Java Mail的封装,使用起来十分的方便,但是我在使用他的时候发现,使用纯文本的内容发送,结果是乱码,代码如下: public class TestCommonMail { public static void main(String[] args) throws EmailException, MessagingException { SimpleEmail email = new SimpleEmail(); email.setCharset("GB2312"); email.setHostName("smtp.163.com"); email.setSubject("test"); email.addTo(" test@163.com "); email.setFrom(" test@163.com "); email.setMsg("我的测试"); email.setAuthentication("test", "test"); email.send(); } } |
分析了一下commons mail的源码找到了原因。
以下是引用片段: 源码如下: public class SimpleEmail extends Email { public Email setMsg(String msg) throws EmailException, MessagingException { if (EmailUtils.isEmpty(msg)) { throw new EmailException("Invalid message supplied"); } setContent(msg, TEXT_PLAIN); return this; } } Email代码片段 public void setContent(Object aObject, String aContentType) { this.content = aObject; if (EmailUtils.isEmpty(aContentType)) { this.contentType = null; } else { // set the content type this.contentType = aContentType; // set the charset if the input was properly formed String strMarker = "; charset="; int charsetPos = aContentType.toLowerCase().indexOf(strMarker); if (charsetPos != -1) { // find the next space (after the marker) charsetPos += strMarker.length(); int intCharsetEnd = aContentType.toLowerCase().indexOf(" ", charsetPos); if (intCharsetEnd != -1) { this.charset = aContentType.substring(charsetPos, intCharsetEnd); } else { this.charset = aContentType.substring(charsetPos); } } } } email.send();的send方法将调用 public void buildMimeMessage() throws EmailException { try { this.getMailSession(); this.message = new MimeMessage(this.session); if (EmailUtils.isNotEmpty(this.subject)) { if (EmailUtils.isNotEmpty(this.charset)) { this.message.setSubject(this.subject, this.charset); } else { this.message.setSubject(this.subject); } } // ======================================================== // Start of replacement code if (this.content != null) { this.message.setContent(this.content, this.contentType); } // end of replacement code // ======================================================== else if (this.emailBody != null) { this.message.setContent(this.emailBody); } else { this.message.setContent("", Email.TEXT_PLAIN); } if (this.fromAddress != null) { this.message.setFrom(this.fromAddress); } else { throw new EmailException("Sender address required"); } if (this.toList.size() + this.ccList.size() + this.bccList.size() == 0) { throw new EmailException( "At least one receiver address required"); } if (this.toList.size() > 0) { this.message.setRecipients( Message.RecipientType.TO, this.toInternetAddressArray(this.toList)); } if (this.ccList.size() > 0) { this.message.setRecipients( Message.RecipientType.CC, this.toInternetAddressArray(this.ccList)); } if (this.bccList.size() > 0) { this.message.setRecipients( Message.RecipientType.BCC, this.toInternetAddressArray(this.bccList)); } if (this.replyList.size() > 0) { this.message.setReplyTo( this.toInternetAddressArray(this.replyList)); } if (this.headers.size() > 0) { Iterator iterHeaderKeys = this.headers.keySet().iterator(); while (iterHeaderKeys.hasNext()) { String name = (String) iterHeaderKeys.next(); String value = (String) headers.get(name); this.message.addHeader(name, value); } } if (this.message.getSentDate() == null) { this.message.setSentDate(getSentDate()); } if (this.popBeforeSmtp) { Store store = session.getStore("pop3"); store.connect(this.popHost, this.popUsername, this.popPassword); } } catch (MessagingException me) { throw new EmailException(me); } } |
由代码可以知道纯文本方式最终调用了Java Mail的
message.setContent(this.content, this.contentType);
content是内容
contentType是类型,如text/plain,
(我们可以试试直接用Java mail发邮件,设置文本内容不使用setText方法,也使用setContent("测试", "text/plain")方式,你可以看到内容也是乱码)
关键就在于text/plain,我们改成text/plain;charset=gb2312,ok乱码解决了。在commons mail我们看SimpleEmail 类中setMsg方法调用的就是 setContent(msg, TEXT_PLAIN);我们只需要将Email类中的常量TEXT_PLAIN修改一下加入 charset=你的字符集 ,重新打包jar,这样就可以了 。