乱码问题
2013-09-25 05:55
155 查看
在中文环境下编程,难免会遇到乱码问题,这是因为不同的条件下对于编码的要求不相同,所以如果在我们的程序中,对于同一段信息使用的字符集(charset)不同,那信息中的中文就会变成乱码。
常见的乱码有三种,一是全问号,像"??????";二是特殊符号加一奇怪的繁体字,像"!_灑";第三种是包含了很多百分号和字母,像"A%KT%%F",这种情况其实不算乱码,只是还没有经过解码的字符串,下面我们还会提到。
因为项目的原因,我有幸在半个月的时间里接触到了几种不同情况下的乱码,花费了不少的时间和精力来解决,这里就把他们总结一下,希望能对遇到相似问题的朋友提供一些帮助。
根据乱码出现位置的不同,我把他们分为4类,然后根据具体的情况来分析解决:
1.字符串传输过程中出现乱码
这个是最底层的乱码,一般来说,使用web容器和常用的mvc框架时,其内部已经自动执行了转码的操作,所以在前后台调试的时候,突然发现某个变量在debug时变成了乱码,的确是挺讨厌的。解决的方法同样底层,我们可以强制在字符串发出和接受的两端对其进行编码/解码,比如在后台编码,前台进行解码。此时前后台传递的,就是上面提到的第三种乱码。
后台代码:
[html] view
plaincopy
return URLEncoder.encode(optionValue.toString(), "UTF-8");
前台代码:
[javascript] view
plaincopy
optionValues = decodeURIComponent(optionValues)
2.压缩文件时,内容乱码
这个是jdk里不大不小的一个bug,因为其在内部实现时默认指定了UTF-8作为唯一字符集,而且不可更改。解决这个问题有两种方法,一是修改jdk的代码,强制换掉字符集,但是这样程序就失去了移植性,所以并不推荐;二是使用第三方的压缩方法,比如这里使用的是commons-compress-1.4.1.jar里提供的方法:
代码片段:
[java] view
plaincopy
OutputStream out = null;
BufferedOutputStream bos = null;
ZipArchiveOutputStream zaos = null;
try {
out = new FileOutputStream(new File(outputFilePath));
bos = new BufferedOutputStream(out);
zaos = new ZipArchiveOutputStream(bos);
zaos.setEncoding("UTF-8");
for (int i = 0; i < inputFilePaths.size(); i++) {
File file = new File(inputFilePaths.get(i));
zaos.putArchiveEntry(new ZipArchiveEntry(file.getName()));
IOUtils.copy(new FileInputStream(file.getAbsolutePath()), zaos);
zaos.closeArchiveEntry();
}
zaos.flush();
bos.flush();
out.flush();
} finally {
close(zaos, bos, out);
}
3.压缩文件时,文件名乱码
这个问题不大不小,解决起来倒也简单,把程序中使用的原生java.util.zip.ZipOutputStream替换成ant.jar的org.apache.tools.zip.ZipOutputStream即可,代码完全兼容,只是后者多了一个设置字符集的方法。
代码:
[java] view
plaincopy
zipOutputStream.setEncoding("UTF-8");
4.文件传输时,文件名乱码
在实现下载操作时,后台传回的文件可能本身是好好的,但一弹出下载框就乱码了,大家可能一下子就反应过来时http的headers拼的有问题,但是这种文件名的乱码,不是简单的添上一句"charset=utf-8"就能解决的,而应该在向请求附上文件时,对文件名进行处理。
代码:
[java] view
plaincopy
headers.setContentDispositionFormData("attachment", new String(exportFile.getName().getBytes("utf-8"), "ISO8859-1"));
[java] view
plaincopy
[java] view
plaincopy
PS:5.数据库乱码
[java] view
plaincopy
<span style="white-space:pre"> </span>问题表征为,所有的汉字变成了全角问号“?”,原因是简易客户端plsql的的字符集没有配置或者与数据源配置冲突。解决方法是配置环境变量NLS_LANG,具体到本项目组中,应该设置为SIMPLIFIED CHINESE_CHINA.ZHS16GBK。
[java] view
plaincopy
<span style="white-space:pre"> </span>其实这个问题在每次登陆plsql的时候都可以看到现象,就是那个登陆成功后弹出的那个对话框,仔细看就会发现软件列出了你本地和数据源的字符集不同,最极端的情况是,警告你本地没有配置从而与数据源的字符集不符,这时就一定会出现乱码了。
常见的乱码有三种,一是全问号,像"??????";二是特殊符号加一奇怪的繁体字,像"!_灑";第三种是包含了很多百分号和字母,像"A%KT%%F",这种情况其实不算乱码,只是还没有经过解码的字符串,下面我们还会提到。
因为项目的原因,我有幸在半个月的时间里接触到了几种不同情况下的乱码,花费了不少的时间和精力来解决,这里就把他们总结一下,希望能对遇到相似问题的朋友提供一些帮助。
根据乱码出现位置的不同,我把他们分为4类,然后根据具体的情况来分析解决:
1.字符串传输过程中出现乱码
这个是最底层的乱码,一般来说,使用web容器和常用的mvc框架时,其内部已经自动执行了转码的操作,所以在前后台调试的时候,突然发现某个变量在debug时变成了乱码,的确是挺讨厌的。解决的方法同样底层,我们可以强制在字符串发出和接受的两端对其进行编码/解码,比如在后台编码,前台进行解码。此时前后台传递的,就是上面提到的第三种乱码。
后台代码:
[html] view
plaincopy
return URLEncoder.encode(optionValue.toString(), "UTF-8");
前台代码:
[javascript] view
plaincopy
optionValues = decodeURIComponent(optionValues)
2.压缩文件时,内容乱码
这个是jdk里不大不小的一个bug,因为其在内部实现时默认指定了UTF-8作为唯一字符集,而且不可更改。解决这个问题有两种方法,一是修改jdk的代码,强制换掉字符集,但是这样程序就失去了移植性,所以并不推荐;二是使用第三方的压缩方法,比如这里使用的是commons-compress-1.4.1.jar里提供的方法:
代码片段:
[java] view
plaincopy
OutputStream out = null;
BufferedOutputStream bos = null;
ZipArchiveOutputStream zaos = null;
try {
out = new FileOutputStream(new File(outputFilePath));
bos = new BufferedOutputStream(out);
zaos = new ZipArchiveOutputStream(bos);
zaos.setEncoding("UTF-8");
for (int i = 0; i < inputFilePaths.size(); i++) {
File file = new File(inputFilePaths.get(i));
zaos.putArchiveEntry(new ZipArchiveEntry(file.getName()));
IOUtils.copy(new FileInputStream(file.getAbsolutePath()), zaos);
zaos.closeArchiveEntry();
}
zaos.flush();
bos.flush();
out.flush();
} finally {
close(zaos, bos, out);
}
3.压缩文件时,文件名乱码
这个问题不大不小,解决起来倒也简单,把程序中使用的原生java.util.zip.ZipOutputStream替换成ant.jar的org.apache.tools.zip.ZipOutputStream即可,代码完全兼容,只是后者多了一个设置字符集的方法。
代码:
[java] view
plaincopy
zipOutputStream.setEncoding("UTF-8");
4.文件传输时,文件名乱码
在实现下载操作时,后台传回的文件可能本身是好好的,但一弹出下载框就乱码了,大家可能一下子就反应过来时http的headers拼的有问题,但是这种文件名的乱码,不是简单的添上一句"charset=utf-8"就能解决的,而应该在向请求附上文件时,对文件名进行处理。
代码:
[java] view
plaincopy
headers.setContentDispositionFormData("attachment", new String(exportFile.getName().getBytes("utf-8"), "ISO8859-1"));
[java] view
plaincopy
[java] view
plaincopy
PS:5.数据库乱码
[java] view
plaincopy
<span style="white-space:pre"> </span>问题表征为,所有的汉字变成了全角问号“?”,原因是简易客户端plsql的的字符集没有配置或者与数据源配置冲突。解决方法是配置环境变量NLS_LANG,具体到本项目组中,应该设置为SIMPLIFIED CHINESE_CHINA.ZHS16GBK。
[java] view
plaincopy
<span style="white-space:pre"> </span>其实这个问题在每次登陆plsql的时候都可以看到现象,就是那个登陆成功后弹出的那个对话框,仔细看就会发现软件列出了你本地和数据源的字符集不同,最极端的情况是,警告你本地没有配置从而与数据源的字符集不符,这时就一定会出现乱码了。
相关文章推荐
- core dump
- GNU MAKE指南
- Disk Opt
- C#汉字转拼音,自动识别多音字,带声调,提供正向、逆向、双向分词算法的小程序
- 软工第二周团队作业 - 软件分析和用户需求调查之 必应词典桌面版
- JAP1.0移植到JAP2.0时 其中涉及到Date,TimeStamp的需要添加@Temporal
- 软件工程个人项目--Word frequency program
- 第一次个人作业总结
- Project: Individual Project - Word frequency program-11061154周辰光
- 在Mac OS X中完善PHP环境:memcache、mcrypt、igbinary
- cocos studio
- 使用 MonoDevelop 调试 Unity3D 的正确步骤
- oracle 递归查询
- Week2 Teamework from Z.XML 软件分析与用户需求调查(五)从对比中看见必应助手发展空间
- oracle 交集和并集
- 【软件工程-Teamwork 2】必应词典软件手机版测试报告
- Week2 Teamework from Z.XML 软件分析与用户需求调查(四)Bing桌面及助手的现状与发展
- 月光微博客
- Week2 Teamework from Z.XML 软件分析与用户需求调查(三)必应助手体验评测
- android camera 竖直拍照 获取竖直方向照片 做缩放处理