浏览 4841 次
锁定老帖子 主题:JavaMail的编码问题
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-03-25
最后修改:2009-03-25
先介绍一下javamail的编码: 1、内容编码: 当一段 Text 或者 HTML 通过电子邮件传送时,发送的内容首先通过一种指定的字符编码转化成“字节串”,然后再把“字节串”通过一种指定的传输编码(Content-Transfer-Encoding)进行转化得到另一串“字节串”。比如,打开一封电子邮件源代码,可以看到类似的内容: Content-Type: text/plain;charset="gb2312" Content-Transfer-Encoding: base64 sbG+qcrQuqO17cf4yee74bGjz9W7+b3wudzA7dbQ0MQNCg0KvPKzxqO6uqO17cnnsaPW0NDEDQoNCg== 最常用的 Content-Transfer-Encoding 有 Base64 和 Quoted-Printable 两种。在对二进制文件或者中文文本进行转化时,Base64 得到的“字节串”比 Quoted-Printable 更短。在对英文文本进行转化时,Quoted- Printable 得到的“字节串”比 Base64 更短。 2、标题编码: 邮件的标题,用了一种更简短的格式来标注“字符编码”和“传输编码”。比如,标题内容为 "中",则在邮件源代码中表示为: // 正确的标题格式 Subject: =?GB2312?B?1tA=?= //subject是指标题内容 其中, 第一个“=?”与“?”中间的部分指定了字符编码,在这个例子中指定的是 GB2312。 “?”与“?”中间的“B”代表 Base64。如果是“Q”则代表 Quoted-Printable。 最后“?”与“?=”之间的部分,就是经过 GB2312 转化成字节串,再经过Base64 转化后的标题内容。 如果“传输编码”改为 Quoted-Printable,同样,如果标题内容为 "中": // 正确的标题格式 Subject: =?GB2312?Q?=D6=D0?= 如果阅读邮件时出现乱码,一般是因为“字符编码”或“传输编码”指定有误,或者是没有指定。比如,有的发邮件组件在发送邮件时,标题 "中": // 错误的标题格式 Subject: =?ISO-8859-1?Q?=D6=D0?= 这样的表示,实际上是明确指明了标题为 [0x00D6, 0x00D0],即 "ÖÐ",而不是 "中"。 解决乱码方法: 1.邮件主题乱码或附件名乱码 解决办法: 在调用setSubject()设置主题时使用Base64编码。例如: sun.misc.BASE64Encoder enc = new sun.misc.BASE64Encoder(); //mailMessage是一个javax.mail.Message,而mailInfo是我们自己写的一个类,作用是存放邮件信息。mailInfo.getSubject()是MailInfo类中的方法,目的是获取邮件的主题。 mailMessage.setSubject("=?utf8?B?"+enc.encode(mailInfo.getSubject().getBytes())+"?="); 2.接收邮件时,获取某些邮件发送程序发送的email地址,发送地址显示为乱码 解决办法: 对含有中文的发送地址,使用MimeUtility.decodeTex方法,对其他则把地址从ISO8859_1编码转换成gbk编码,见下例 public static String getFrom(Message msg){ String from=""; try{ if(msg.getFrom()[0]!=null) from=msg.getFrom()[0].toString(); if(from.startsWith("=?GB")||from.startWith(“=?gb”)){ from=MimeUtility.decodeText(from); }else{ from=StringUtil.toChinese(from); } }catch(Exception e){ e.printStackTrace(); } from=StringUtil.replaceStr(from,“<”,“<”);// replaceStr为字符串替换函数 from=StringUtil.replaceStr(from,">",">"); return from; } ///////////////////StringUtil的toChinese方法////////////////////////// public static String toChinese(String strvalue){ try{ if(strvalue==null) return null; else{ strvalue = new String(strvalue.getBytes("ISO8859_1"), "GBK"); return strvalue; } }catch(Exception e){ return null; } }3.接收邮件时,获取某个邮件的中文附件名,出现乱码 解决办法: 对于用base64编码过的中文,则采用base64解码,否则对附件名进行ISO8859_1到gbk的编码转换,例如: String temp=part.getFileName();//part为Part实例 if((temp.startsWith("=?GBK?B?")&&temp.endsWith("?=")) ||(temp.startsWith("=?gbk?b?")&&temp.endsWith("?="))){ temp=StringUtil.getFromBASE64(temp.substring(8,temp.indexOf("?=")-1)); }else{ temp=StringUtil.toChinese(temp);//该方法如前所叙 } /////////////StringUtil的getFromBASE64方法///////// public static String getFromBASE64(String s) { if (s == null) return null; BASE64Decoder decoder = new BASE64Decoder(); try { byte[] b = decoder.decodeBuffer(s); return new String(b); } catch (Exception e) { return null; } }乱码问题的调试步骤总结: 基本上在javamail中碰到的中文乱码问题就这么多了,如果你的程序出现了中文乱码,首先不要惊慌,可用多个其他的邮件发送或接收程序进行验证,看是在哪个环节出现了问题,然后再仔细对照原文和乱码,调用相应的编码解码方法就行了。 最后,希望这篇短文能对你有所启发,祝你成功。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |