1 各种编码介绍
字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。字符集是多个字符的集合,字符集种类较多,每个字符集包含的字符个数不同,常见字符集名称:ASCII字符集、GB2312字符集、BIG5字符集、 GB 18030字符集、Unicode字符集等。计算机要准确的处理各种字符集文字,需要进行字符编码,以便计算机能够识别和存储各种文字。
ASCII
ASCII(American Standard Code for Information Interchange,美国信息互换标准代码)是基于罗马字母表的一套电脑编码系统,它主要用于显示现代英语和其他西欧语言。它是现今最通用的单字节编码系统,并等同于国际标准ISO 646。
ANSI
ASCII字符集,以及由此派生并兼容的字符集,如:GB2312,正式的名称为MBCS(Multi-Byte Chactacter System,多字节字符系统),通常也称为ANSI字符集。ANSI编码表示英文字符时用一个字节,表示中文用两个字节,而unicode不管表示英文字符还是中文都是用两个字节来表示。
不同的国家和地区制定了不同的标准,由此产生了 GB2312, BIG5, JIS 等各自的编码标准。这些使用 2 个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。在简体中文系统下,ANSI 编码代表 GB2312 编码,在日文操作系统下,ANSI 编码代表 JIS 编码。
GB2312
似乎是最普通的编码方式,是ANSI 编码的代表。80年代诞生,收录6000多汉字。几乎所有的中文系统都会支持GB2312。
GB2312的编码方式和古老的区位码颇有渊源。汉字的区位码每两位加上0xA0就是计算机中的GB2312码。比如“啊”区位码是1601,GB码是0xB0A1。B0 = 16 + A0,A1 = 01 + A0。
GBK
是GB2312的扩展方案,使用了原来编码空间的一些空白,增加了一些汉字,因此向下兼容GB2312。是Windows中文系统的缺省字符集。
可以用Windows的记事本看一看GBK的编码。打开记事本写几个字:“在CSDN写Blog”。保存类型为“ANSI”。注意ANSI是英语文字的编码方式(美国国家标准),可不是汉字的。这里“ANSI”的意思就是采用系统默认的字符编码方式编码。不同 ANSI 编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段 ANSI 编码的文本中。
GB18030
国内最新的编码方案。支持了更多的字符,甚至包括了蒙文,藏文之类。
GB18030的独特之处在于它向下兼容了GBK,但又扩展了编码空间。GB18030采用1字节,2字节,4字节三种方式来编码。
Unicode
国际统一的编码方式。据我理解,似乎Unicode标准试图用2个字节覆盖全世界所有的书写符号,两字节总共65535个编码位,据说现在还剩下3w多没有编码。前途无量,前途无量。
Unicode是真正的纯两个字节的编码方案。所有的字符一视同仁,原有的ASCII字符通过在高位加00来兼容Unicode。这使得Unicode成为非常危险的编码方案。一旦某一个字节丢失,其后的信息将全部作废。
UTF-8
UTF-8是Unicode的其中一个使用方式。对于汉字居多的文本来说,UTF-8将大部分是每个汉字三个字节的情况,反而会增加了码长。但UTF-8的一大好处就是避免了Unicode“一个烂鱼坏得一锅腥”的糟糕情况。因为UTF-8每一个字有严密的编码规则,如果传输中丢掉了一个字节,结果不会影响很多。
ISO-8859-1
最后说一下ISO-8859-1是因为它根本就不是汉字编码。据“维基百科”记载,ISO 8859是给除英语之外的其他字母文字做编码规范的。它占用ASCII码的0xA0~0xFF,每个字符集扩展96个字符。ISO-8859(多了一个连字号)则是ISO 8859加上原有的ASCII中的字符构成的编码规范。
说到ISO-8859-1因为它是许多未汉化的西文操作系统的编码,比如Linux。最主要的原因是我发现我的手机的缺省编码也是它。许多西文的数据库等等也只认识8859规范。
注意:几乎所有的WEB容器在其内部默认的字符编码格式都是以ISO-8859-1为默认值的,同时,几乎所有的浏览器在传递参数时都是默认以UTF-8的方式来传递参数的。
2 乱码问题
Java应用中必须注意几个编码设置:
项目(容器)编码(可以继承自操作系统)
Java文件编码(可以继承自容器)
jsp文件编码(pageEncoding可以控制文件编码:前提是属性设置文件编码继承自页面内容)
jsp页面或html页面还有contentType可以控制浏览器显示编码
修改服务器默认编码
首选项-general-workspace-text file encoding(改为gbk或gb2312)
修改jsp默认编码
首选项-myeclipse-file and editor-jsp-encoding改为utf-8(选项为iso 10646/unicode(utf-8))
//乱码产生的原因是servlet在接受request后处理接受数据的语句时采用iso-8859-1解码成****
//需要request码表,不行的话需要先用iso-8859-1编码,再用原来的码解码
//只对post提交
//get提交只能采用手工矫正String a=new String(a.getBytes("iso-8859-1"),"utf-8");
//request与response都是在本程序中使用,response对以后的处理,request对接受的处理,事实上没有现在,呵呵
用a传值
需要 String a=request.getParameter("a");
a=new String(a.getBytes("iso-8859-1"),"utf-8");
out.print(a);
//原因是超链接传值属于get传值
猜想下面的原因:先用gbk编码,再用iso-8859-1解码。为了满足文件下载底层编码解码原则
文件下载底层处理中文的时候先用iso-8859-1编码,再用gbk解码。
response.addHeader("Content-Disposition", "attachment;filename="
+ new String(file.getName().getBytes("gbk"),"iso-8859-1"));//我的响应默认是gbk解码,系统默认是iso-8859-1编码处理
有哪些默认设置的编码…………系统到底有哪些编码我不知道
response.setCharacterEncoding("utf-8");控制输出内容的编码
response.setContentType("text/html;charset=utf-8");控制浏览器显示
用标签meta模拟一个http响应头,控制浏览器
//程序以什么码表输出,程序就一定要控制浏览器以什么码表打开
response.setHeader("Content-type","text/html;charset=gb2312");//控制浏览器显示
后面才能使用outputstream输出q=new String(q.getBytes(),"gb2312");
String q="中国";
q=new String(q.getBytes(),"gb2312");
out.print(q);
Encodes this String into a sequence of bytes using the platform's default charset, storing the result into a new byte array.一般默认编码是gb2312,怎么设定?
字符流只能写字符串(字符形式组成的),不能写二进制文件等。字节流什么都能写
jsp中文乱码
首先我们先了解一下问题的原因。一般情况在在每个JSP页的头部都有这样一条语句:
这条语句决定了此页面使用GB2312编码形式,而在数据库中一般用的是iso-8859-1字符集存储数据. 而Java程序在处理字符时默认采用统一的ISO-8859-1字符集(体现Java国际化思想),所以在添加数据时,默认的字符集编码是iso-8859-1,而页面采用的是GB2312,所以就出现乱码问题。为解决此问题应在存储的时候把GB2312换转成iso-8859-1。有此时候在读出时也会出现乱码,那么只需反过来就可以了,把iso-8859-1转换成GB2312。
具体实例归纳了以下几点,也许会对大家有一些帮助。
1、 在建立JSP页面时应该注意在jsp页面的头部加入一下代码
此方法是解决JSP页面显示时的乱码。
2、 有时还需在HTML代码中的中加入这句
3、 在bean中用的是iso-8859-1编码,在jsp中一般用GB2312编码,处理此类乱码问题如下
String str=new String(strName.getBytes(“iso-8859-1”),”GB2312”);
具体用到此方法的地方为,当提交表单到bean(bean的功能是存储数据到数据库)表单提交后,数据库中存入的数据确变成了????,因此在调用bean之前应对编码进行转换,方法:String str=new String(request.getParameter().getBytes(“iso-8859-1”),”GB2312”);
这样,存入数据库的数据库的数据就可见了。
4、 对于页面间的参数传递也可以用这个方法来处理乱码问题:
public String getStr(String str)
{
try
{
String temp_p=str;
byte[] temp_t=temp_p.getBytes("ISO8859-1");
String temp=new String(temp_t);
return temp;
}
catch(Exception e)
{}
return "null";
}
5、 在表单定义时加上这个属性有时也可以解决表单提交过程中出现的乱码
窗体顶端
窗体底端