love fish大鹏一曰同风起,扶摇直上九万里

常用链接

统计

积分与排名

friends

link

最新评论

编码问题(转)

今天看了子华的博客中关于昨晚我们讨论编码方面的问题,发现其中有一个关键点没有谈到。
    情况是这样的:我们现在使用的一个名为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参数来说明文本编码形式。弄清中文显示后面的具体调用过程是彻底解决该类问题的终极之道!

posted on 2006-12-07 14:42 stme 阅读(490) 评论(7)  编辑 收藏引用收藏至365Key

评论

# re: 编码问题 2006-12-07 16:22 BeanSoft

不错, 必须在头部加入下列声明:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="GBK"%>

要不然你就得用编辑器另存为的时候(例如记事本就有这个功能, 但是貌似有问题)转换编码为 UTF-8.

服务器看到 contentType="text/html; charset=UTF-8" 的页面声明的时候, 就认为下面的内容都是 UTF-8, 如果这时候不加上 pageEncoding, 出来的内容自然就是乱码.

因此要么都用 GBK, 要么都用 UTF-8. 可以在 Eclipse 里进行设置让所有的源文件的默认字符集都是 UTF-8. 如果要做开源项目, 强烈建议的是不要用 GBK 格式的编码, 用 UTF-8 是上上策. 还有就是鼓励英文注释, 网页内容国际化, 呵呵.  回复  

# re: 编码问题 2006-12-07 17:00 hahahehe

1、首先我们用编辑器编辑jsp页面代码保存;
2、web服务器对其进行编译,将jsp页面编译成为一个java的class文件;
3、web服务器将其class文件用传输格式在网络上传输;
4、客户端浏览器解析代码生成页面。

非applet的情况下,服务器怎么可能把class传输到网络上去,浏览器又怎么可能解析class?服务器传输的是html,class生成html的过程早在服务器端就已经完成。

乱码的直接原因就在于服务器在头里告诉浏览器的编码 charset=UTF-8 和事实上生成html的编码是不一致的  回复  

# re: 编码问题 2006-12-07 17:13 BeanSoft[匿名]

呵呵, 这段话的确是有点问题...

应该是:
1. 我们用代码编辑器编辑了一个页面(encoding=GBK)
2. Web 服务器调用编译器将其编译为 servlet(编译器也会有个 encoding 选项, 一般都是跟着系统的 encoding 走, 页面有 charset 的话就跟页面的 charset 或者 pageEncoding 一致, 所以有时候不指定JSP编译默认编码, 不同的服务器出来的结果就不一样), (encoding=GBK);
3. 生成 HTML, 这没啥, 直接 write string;
4. 浏览器根据 head 里的 contentType (UTF-8)来判断编码, 或者根据页面里的 meta 来判断编码
<meta http-equiv="content-type" content="text/html; charset=UTF-8">, 什么都没的时候就当成西欧字符集, 具体哪个优先? 印象中是页面里的 meta 优先, 这时候客户需要手工选一个编码才能看到正确的网页.

所以只有这些条件都一致的时候, 才不会乱码, 否则都会乱码. 一般推荐全用 UTF-8(英文服务器环境) 或者 GBK(中文服务器).  回复  

# re: 编码问题 2006-12-08 00:27 weidagang2046

上次看你另一篇文章,对编码分析得很详细,很有帮助。再接再厉!  回复  

# re: 编码问题 2006-12-08 09:44 stme[匿名]

谢谢大家的点评,大家一起进步吧!  回复  

# re: 编码问题 2006-12-08 13:44 laoshi

>>utf-8只是用于在数据传输时将字符串分割成字节传输出去,它对于unicode编码有着严格的一一对应关系,而对于gb2312、gbk、gb18030之类的中文编码是没有对应关系的。gb2312、gbk、gb18030是在ascii编码之上进行的中文编码开发,所以它们是与ascii相兼容的
gb18030也和unicode有着严格的一一对应关系,gb2312、gbk和unicode的子集有着严格的一一对应关系
UTF-8和gb18030都是所谓的外码标准
“gb2312、gbk、gb18030是在ascii编码之上进行的中文编码开发,所以它们是与ascii相兼容的”是错误的,只能说UTF-8以及国标编码的单字节编码区和ascii的0~7F区的编码是一致的。
Notepad++和UltraEdit的ascii其实并不是ascii,而是指Windows平台的本地多字节字符集,一般咱们用的中文Windows上就是gbk  回复  

# re: 编码问题2006-12-08 16:13 luguoren

”gb18030也和unicode有着严格的一一对应关系,gb2312、gbk和unicode的子集有着严格的一一对应关系“
这个是对的吗?本人好像没有看到这样的资料,gb18030只是一部分与unicode对应,不会是全部一一对应吧  回复  

posted on 2006-12-10 11:46 liaojiyong 阅读(418) 评论(0)  编辑  收藏 所属分类: JSP


只有注册用户登录后才能发表评论。


网站导航: