乱码问题,是对中文系统的一个挑战,只要你在中文环境下做开发,如果没有遇到乱码,那是你的福份,应该谢天谢地。
近些天做了一个小应用,用来解析MMS GW 发来的 MO,MO的封包规则很简单,仅仅采用MIME封装的base64格式,然后将MIME包写入XML字符串,通过HTTP传输。多么简单的冬冬啊,但是问题出现,当本人自认为音档,图片档,视频档都已经顺利处理后,才发现文本档的存储出现乱码问题!于是乎继续敲击键盘,需求正解。
之前看过很多关于乱码的文章,也处理过很多乱码的问题,但本次,没能搞定!以下简单描述一下过程和本人的解决之道:
1、MIME封装时,文本已经是UTF-8编码格式,当封装MIME时,Content-Transfer-Encoding设置成base64。
2、经过查询MMS GW端的base64格式的文本字符串与Client端log中的文本字符串一模一样。(请注意:上面已经说明,mime包被封装进XML中,并以http方式传输)
3、乱码问题
采用javax.mail.internet.MimeMultipart读取MIME,部分代码如下
String moContent;//mime包字符串流
String contenttype;//boundary分割标识
MimeMultipart content = new MimeMultipart(new javax.mail.util.ByteArrayDataSource(moContent, contenttype));
if (content != null) {
MimeAnalyzer mimeAnalyzer = new MimeAnalyzer();
IMediaElement[] attachments = mimeAnalyzer.getAttachments((MimeMultipart) content);
if (attachments != null) {
for (int i = 0; i < attachments.length; i++) {
//此处获得的byte[] 是有问题的,并不是正确的,因此导致中文出现乱码。如果有了解内情的高手,请指点迷津,不胜感激
byte[] mmsBody = attachment.getContent();
}
}
}
4、解决方案
虽然通过byte[] mmsBody = attachment.getContent();获取的字节流存在问题,但MIME字符流本身是正确的,因此采用如下方式获取正确的文本字符串,代码如下:
String moContent;//mime包字符串流
String contenttype;//boundary分割标识
MimeMultipart content = new MimeMultipart(new javax.mail.util.ByteArrayDataSource(moContent, contenttype));
//写入新的MIME
MimeMessage message =new MimeMessage();
int num = content.getCount();
for (int i = 0; i < num; i++) {
message.addBodyPart(content.getBodyPart(i), i);
}
if (content != null) {
MimeAnalyzer mimeAnalyzer = new MimeAnalyzer();
IMediaElement[] attachments = mimeAnalyzer.getAttachments((MimeMultipart) content);
if (attachments != null) {
for (int i = 0; i < attachments.length; i++) {
//与之前的获取byte方式不同,请注意
if( attachment.getContentType().toString().indexOf("text")>=0){
BufferedReader input = null;
try {
input = new BufferedReader(new InputStreamReader(message.getBodyPart(i).getInputStream()));
String tempStr = input.readLine();
StringBuffer bs = new StringBuffer("");
while (tempStr != null) {
bs.append(tempStr);
tempStr = input.readLine();
}
byte[] mmsBody = bs.toString().getBytes();
} catch (Exception e) {}
try {
if(input!=null){input.close();}
} catch (IOException e) {}
}
}
}
}
5、费解之处
本人一直没有找到为何直接获取文本字节流( attachment.getContent()),这种方式出现乱码的原因,在我的测试环境中,采用同一台server测试,所以排除系统环境和JVM环境的字符集不同问题。望有解的高手请告知,谢谢!