Java中常出现的乱码问题总结

转载请注明,大飞_Rflyee:http://blog.csdn.net/rflyee/article/details/13274907


       编码也就是计算机能识别的数据与人类友好的数据的翻译过程。计算机的基本存储单位是byte,人类友好语言(汉语英语等各种语言)用char存储吧。那么编码其实就可以理解为char-byte、byte-char这样的过程。这样char-byte之间的翻译就需要一个标准了,可惜的是每个国家根据自己国家的母语设计出了不同的翻译标准,这边导致不同标准之间的翻译过程出现不统一,自然乱码问题就出现了。

        常见的编码标准有很多,常用的能用识别中文的有GB2312、GBK、UTF-8、UTF-16。其中,GB2312与GBK类似,但是GBK范围更大,所以GB2312、GBK之间应该选用GBK;UTF-16每个字符都用2个字节编码,对于ASCII字符浪费空间,另外如果编码过程中有一个字节损坏则会影响后边的所有,但是编码效率相对高;UTF-8最大的特点是变长编码,1-4个字节来表示一个符号,节省空间,并且解决了UTF-16的安全问题。因此,utf-8适合网络传输(安全),utf-16适合本地磁盘和内存之间。

Java Web中常见的乱码:

1、servlet中获取请求参数乱码
(1)get方式:

jsp提交到servlet中,servlet中获取

String getStr = request.getParameter("username");

解决1:(实验不可行)配置Connector,

<Connector URIEncoding="UTF-8" useBodyEncodingForURI="true" />

解决2:手动解码
String Str = request.getParameter("username");
String Str2 = new String(getStr.getBytes("iso8859-1"),"utf-8");
syso(Str2);//此时的字符串才是不乱码的。
(2)post方式
解决:
request.setCharacterEncoding("utf-8");//这个只对http中请求实体有效,请求头,请求行无效。这也是get方式不能使用次方法解码的原因。
String postStr = request.getParameter("username");
System.out.println("postStr:"+postStr);

2、servlet中有输出中文到浏览器
response.setCharacterEncoding("utf-8");		//设置服务器内将字符转换为字节时的编码集,必须在getWriter()之前调用
response.setContentType("text/html;chatset=utf-8");//此句话隐含已经将上一句实现,因此上一句可以省略。
response.getWriter().write("中国");

3、请求头中(设置请求头实现文件下载时)
请求头中信息必须以ASCII编码,如果有非ASCII,必须手动转换。
转换方法:URLEncoding.encode("中国","utf-8");
response.setHeader("Content-Disposition","attachment;filename="+URLEncoding.encode("美女","utf-8")+".jpg");
4、jsp页面中的乱码:
输出响应正文时出现的中文乱码问题 
<%@ page pageEncoding="UTF-8"%>足矣
(1)JSP引擎将JSP页面翻译成Servlet源文件时可能导致中文乱码问题 

JSP引擎将JSP源文件翻译成的Servlet源文件默认采用UTF-8编码,而JSP开发人员可以采用各种字符集编码来编写JSP源文件(默认iso8859-1),因此,JSP引擎将JSP源文件翻译成Servlet源文件时,需要进行字符编码转换。 

(2)在翻译过来的servlet向浏览器发送数据时也可能乱码。发送时的编码和浏览器打开时的编码不一致。如以上2

解决:在myeclipse等IDE中只需在jsp页面声明<%@ page pageEncoding="UTF-8"%>即可智能为整个过程统一编码。

5、xml乱码
将节点写出到XML文件中去
(1)方法1:
调用Node提供的write(Writer writer) 方法,使用默认方式将节点输出到流中:
node.write(new FileWriter("book.xml"));
乱码问题:
Dom4j在将文档载入内存时使用的是文档声明中encoding属性声明的编码集进行编码, 如果在此时使用writer输出时writer使用的内部编码集与encoding不同则会有乱码问题。
FileWriter默认使用操作系统本地码表即gb2312编码,并且无法更改。
此时可以使用OutputStreamWriter(FileOutputStream("filePath"),"utf-8");的方式自己封装 一个指定码表的Writer使用,从而解决乱码问题。
(2)方式2:
利用XMLWriter写出Node:
 XMLWriter writer = new XMLWriter(new  FileWriter("output.xml"));
 writer.write(node);
writer.close();
乱码问题:
a、使用这种方式输出时,XMLWriter首先会将内存中的docuemnt翻译成UTF-8格式的document,在进行输出,这时有可能出现乱码问题。可以使用OutputFormat 指定XMLWriter转换的编码为其他编码。
OutputFormat format = OutputFormat.createPrettyPrint();             
format.setEncoding("GBK");       
XMLWriter writer = new XMLWriter(new FileWriter("output.xml"),format);

b、Writer使用的编码集与文档载入内存时使用的编码集不同导致乱码,使用字节流或自己封装指定编码的字符流即可(参照方法1)。


延伸阅读:http://www.ibm.com/developerworks/cn/java/j-lo-chinesecoding/index.html


转载请注明,大飞_Rflyee:http://blog.csdn.net/rflyee/article/details/13274907

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值