出现乱码问题主要是因为字符集编码的问题。而java的底层是Unicode编码的,用Unicode处理字符,单在文件和流中是使用字节流的。因此java需要对字节流和字符进行转换。转换中,编码和解码使用的字符集不一致,就会导致中文乱码问题。
中文系统的默认编码方式是GBK,java会根据操作系统的默认编码字符集来决定字符串的编码。
一、常用字符集
1. ASCII码 是7位编码,编码范围是0x00-0x7F。ASCII字符集包括英文字母、阿拉伯数字和标点符号等字符。
2. GB2312 是基于区位码设计的,编码范围 0xA1A1-0x7E7E。GB2312字符集 除常用简体汉字字符 外还包括希腊字母、日文平假名及片假名字母、俄语西里尔字母等字符,未收录繁体中文汉字和一些生僻字。别名 EUC-CN。
可以这样理解,区位码是字符集,GB2312(EUC-CN)是对应这种字符集的编码。
3. GBK 是GB2312编码的超集,向下完全兼容GB2312。 编码范围是0x8140-0xFEFE。别名CP936,两者差不多。
注意:
低字节 是0x40-0x7E的GBK字符有一定特殊性,因为这些字符占用了ASCII码的位置,这样会给一些系统带来麻烦。例如 有 些系统中用0x40-0x7E中的字符(如“|”)做特殊符号,在定位这些符号时又没有判断这些符号是不是属于某个 GBK字符的低字节,这样就会造成错误判断。在支持GB2312的环境下就不存在这个问题。需要注意的是支持GBK的环境中小于0x80的某个字节未必就 是ASCII符号;另外就是最好选用小于0×40的ASCII符号做一些特殊符号,这样就可以快速定位,且不用担心是某个汉字的另一半。Big5编码中也 存在相应问题。
4. Unicode 是统一码,为世界每种语言的每一个字符设置唯一的二进制编码。 Unicode用一些基本的保留字符制定了三套编码方式。它们分别是UTF-8,UTF-16和UTF-32。通常所说的Unicode即为UTF-16,用16位表示一个字符。容易把人搞晕的字符集和编码方式(charset/encoding) ,狭义的字符集,只是一个字符的集合,不包括编码方式。这里Unicode是字符集,UTF-8,UTF-16,UTF-32是编码方式。
5. UTF-8 是一种国际编码,通用性强。用8位表示英文,用24位表示中文。而GBK,GB2312都是用16位表示中文的。由于UTF-16不能和现行的基于ascii的编码方案兼容,所以提示出了UTF-8。UTF-8是专为Unicode设计的传输格式。它可以用来表示 Unicode 标准中的任何字元,而且其编码串流中的第一个位元组仍与 ASCII 兼容,令原来处理 ASCII 字符的软件无需或只作少量改动后,便可继续使用。因此, 它逐渐成为电子邮件、网页及其他储存或传送文字的应用中,优先采用的编码 。
6. ISO8859 不是一个标准,而是一系列的标准。详细说明http://baike.baidu.com/view/471161.htm
I SO8859-1 ,即Latin-1,是西欧常用字符,包括德法两国的字母。
二、常见用处
1.在JSP页面中,在每个页面的第一行添加代码
<%@ page language="java" contentType="text/html;charset=gb2312"%>,字符集设置成GB2312
2.在request,或其他JSP内置对象获取参数时,需要进行字符串转换。例如:
<%
String nameTemp = (String) request.getParameter("uid");
String name= new String(nameTemp.getBytes("iso8859-1"));
%>
3.在Servlet的输出响应中,例如:
public void doGet(***){
request.setCharacterEncoding("gb2312");
response.setContentType("text/html;charset=gb2312");// 一定在获取out对象之前
PrintWriter out = response.getWriter();
.......
}
(未整理完....)
三、配置说明
1. pageEncoding="gb2312" 。JSP编译成Servlet时使用的编码。
2. contentType="text/html;charset=gb2312" 。指定服务器响应的编码。
3. request.setCharacterEncoding("gb2312");。指定对客户端请求的编码
4. response.setContentType("text/html;charset=gb2312")。指定对服务器端响应的编码
注意:
1.服务器按照 setCharacterEncoding->contentType->pageEncoding的顺序进行编码。
2.post提交表单时,接收数据的JSP页面需要正确设置request.setCharacterEncoding。否则按照 默认的 ISO8859-1 进行编码,即 Latin-1
四、举例
网上看到的这个例子不错,特引用过来。原文网址
1、getBytes()
String str=”中”;
|
①
|
byte[] bytes = str.getBytes();
|
②
|
bytes = str.getBytes(“ISO-8859-1”);
|
③
|
语 句③:该语句与语句②的区别就是指定了编码方式,此处指定的是ISO-8859-1,即通常所说的Latin-1,该编码采用8bit对字符编码,所以编 码空间中只有256个字符。该编码中只包含了基本的ASCII码和一些扩展的其它西欧字符,所以该字符集中不可能包含中文的“中”字,也就是说Java虚 拟机无法在ISO-8859-1编码集中找到“中”字对应的编码,针对这种情况,就只返回一个问号(?,0x3f)字符,所以此时bytes.length只有1,且bytes[0]=0x3f
2、new String(byte[] bytes, String encoding)
byte[] bytes = {(byte)0xD6, (byte)0xD0, (byte)0x31};
|
①
|
String str = new String(bytes);
|
②
|
str = new String(bytes,”ISO-8859-1”);
|
③
|
未完待续.....