今天看了子华的博客中关于昨晚我们讨论编码方面的问题,发现其中有一个关键点没有谈到。
情况是这样的:我们现在使用的一个名为Notepad++的编辑器,它大体上和UltraEdit类似,是我从sourceforge上下载下载使用的。它有个格式的功能,简单而言就是设置使用ascii编码编辑文档还是使用utf-8编码,其实这里主要是对应非英文方面的字符才发生差异。
如前那篇随笔所述utf-8只是用于在数据传输时将字符串分割成字节传输出去,它对于unicode编码有着严格的一一对应关系,而对于gb2312、gbk、gb18030之类的中文编码是没有对应关系的。gb2312、gbk、gb18030是在ascii编码之上进行的中文编码开发,所以它们是与ascii相兼容的,可以这么理解在我们的文本编辑器中ascii方式编辑的文本是以ascii码保存,而以utf-8方式编辑的文本是以unicode编码保存。
现在,编码的差异就在这里发生了,unicode中的英文部分编码是与ascii相兼容的,具体而言是iso8859-1兼容,所以我们无论用什么编码保存方式保存jsp文件,在网页上显示的都是正确的英文字符。但是对于中文这个保存的格式却非常重要。在了解了jsp页面的显示过程我们就会明白其中的原因。
现在回头来看看jsp文件是经过了哪些步骤才在网页上显示出来的。
1、首先我们用编辑器编辑jsp页面代码保存;
2、web服务器对其进行编译,将jsp页面编译成为一个java的class文件;
3、web服务器将其class文件用传输格式在网络上传输;
4、客户端浏览器解析代码生成页面。
过程大致如上,能够影响编码方面的基本上在1、2、4方面,所以对其进行详细讲解。
我们的编辑器是有一种默认的编码保存方式的。这会到后面java编译器是否将其中的中文进行转换的问题。大家都知道java是以十六位的unicode编码编译、存储java文件的。因为同一个汉字在unicode编码和gb2312编码中的位置是不一样的,(具体而言就是这两种编码没有兼容性,也不能通过公式换算出来,只能通过字符对应表进行转换)
上面指出的保存格式的重要性就在这里体现出来了,这也是很多人容易遗漏之处,当我们用默认格式位gbk的编辑器编辑jsp页面,而在其头部声明charset=utf-8,那么返回的页面会出现乱码,而charset=gb2312则正常显示。本人分析原因在于,在charset=utf-8的声明有误时,java编译器会错误的认为现在保存的文件就是以unicode编码格式保存的文件,所以在编译中就不对其中的中文字符进行gb2312--unicode的转化,而直接将其gb2312指向的编码地址保存为unicode的编码地址。反之,当编辑器的默认编辑保存格式为utf-8时,在jsp中声明为gb2312,就会让编译器画蛇添足的多进行一次中文编码转换,从而乱码出现。
综上所述,编辑器的默认编码方式是在解决中文乱码方面是很重要的一个因素,当然我们可以用pageEncoding参数来说明文本编码形式。弄清中文显示后面的具体调用过程是彻底解决该类问题的终极之道!