宕昌红灯区在哪:学艺要精,思考要慎.--转UTF-8编码的启发

来源:百度文库 编辑:偶看新闻 时间:2024/05/04 22:33:19
学艺要精,思考要慎.--转UTF-8编码的启发

 本次对UUZone
Refactor中一个大动作就是采用UTF-8编码,由于种种的历史原因,uuzone一直采用GBK编码,现在要把这个编码转成为UTF-8的。

本文不打算讨论技术, 所以简单地说明这个工作进展的一个过程:

** 最早的时候*,n年前,我们一个项目需要国际化支持,毫无疑问utf-8是最佳的编码选择,这时候项目组就遇到了问 题:
本地编写的文件中的中文都是GBK编码的, 仅仅设置页面的contentType="text/html; charset=UTF-8",
出来的全是乱码...当然拿GBK的东西直接要求对方用UTF-8看,一定是乱码.

   当时如何解决的过程已经无法了解, 但最终采用的方案是:  用GBK写文件, 然后采用JDK中的native2ascii工具转换. 问题解决了,
但结果就是多了转码的过程, 转码后的jsp文件人不可读.

** 做uuzone了*,  项目组建议采用GBK编码, 因为那个转码工作太繁琐了,而且导致文件不可读, 调试非常麻烦.
于是uuzone就成了GBK的.

   由于采用GBK, 遇到了很多相关的问题... 中途至少有2次我"建议"改用UTF-8,
都被评估认为有太多问题而没有被采纳(郁闷的boss啊...)...

** 发现原来不需要转码!*  终于处于某些原因, 我需要自己动手来研究一些技术细节,
发现native2ascii转码<http://www.uuzone.com/blog/tom/98879.htm>的工作其实并不需要进行.
jsp文件可以直接保存为UTF-8编码, 输出的结果就是UTF-8的...而现在的elips,editplus, ultraedit,
甚至notepad都能保存和识别utf-8的文件.

** 终于下定决心转为UTF-8.* 既然如此, 就没有理由拒绝了. 因此本次refactor项目目标之一就是改用UTF-8.
既然文件打算用utf-8保存, 那么就需要批量转换工具...几下search, 好的工具也找到了.

** 转!*   有工具, 不到20秒, 6000多个文件就从GBK转成了UTF-8文件格式...

** 问题来了!* 项目中的XML, properties文件是否转码呢? 本来计划转...但很快发现,这些文件转掉后,
XML,properties文件的读取都出了不同程度的问题...总之项目将根本无法运行...
原因何在?原来这些UTF-8的文件有一个所谓BOM<http://www.unicode.org.unicode/faq/utf_bom.html>头,也就是告诉你这个文件的编码是什么...不幸的是Java的xml
parser, properties文件parser都不认识这个BOM头<http://www.uuzone.com/blog/tom/98677.htm>
!已经有人把这个作为Bug提交给了SUN并被接受<http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058>,
可是这个bug一直拖了4年,才在去年在Mustang项目(Java
6.0)中解决<http://glaforge.free.fr/weblog/index.php?itemid=151&catid=2>!
我们显然不能用了.

** 幸运的是... *我们可以规避这些问题, 我们并不需要把XML, properties文件转换成UTF-8的, 只要把jsp转了即可.
虽然一个项目中的文件两种保存格式,非常不优雅, 但毕竟这能解决问题啊... 转换完jsp文件,运行项目, 成功! 打开browser...页面也出来了!

** 几乎成功了!* 是的, 几乎成功了...然而在计算机的世界里几乎成功就是不成功. 因为页面上的样式神秘地出了轻微的混乱.
经过n十分钟仔细研究讨论, 终于发现产生的html页面内出现了几个神秘的不可见字符... 就是这些可怕的不可见字符, 破坏了页面的结构.

** 神秘的隐身字符*  和计算机打交道和比人打交道强的一个地方就是在于 -- 如果计算机错了,一定是你错了, 因为计算机一定忠实执行你的指令.
神秘的不可见字符一定有其来历. 经过二进制分析, 找到了这些神秘字符出现的地方 ---jsp include! 每次include就会出现神秘字符,
而这些神秘字符的值也是老朋友了 -- 就是BOM header !

** 难道不能include了?*  原来java显然和xml文件一样对待了这些BOM头, 这些FF FE之类的东西成了输出的一部分. google
去查, 看到一个人显然遇到完全相同的问题, 可惜是个俄罗斯的程序员, 也看不懂其文章... :(

    怎么办?  有同学说: 既然你要UTF-8 (心想: 谁让你是boss呢? 愚蠢的boss啊...:-) ) ,
我们还是用native2ascii吧...  不行!

** 遇到困难要思考.* 思考...

    首先, 为什么java文件不需要转码(java 文件中的中文无论如何都能正确)? 为什么jsp要? jsp不是被预编译成java的吗?

    从那个sun承认的bug, 显然可以得出一个结论, java虚拟机中的file input stream没有能自动很具BOM识别文件编码.

    也许javac是比较native的代码, 能通过操作系统获得native编码类型, 而java内部是unicode的, 所以输出也同样没问题.
而jsp是动态编译的, 预编译器是JVM...其待遇显然和xml等是一样的...

   难道sun公司的人会愚蠢到这种地步? 不可能, 一定是我们愚蠢.继续google 学习...

    不幸的是大部分google上关于这类编码问题的讨论都是不完整的. 但一个神秘的pageEncoding跳进了眼帘,
已经指定了contentType的encoding, 为什么还要指定pageEncoding?  查一下jsp的资料, 显然这正是问题所在!
pageEncoding就是告诉JVM 这个jsp本身采用的encoding, 默认采用iso-8859. 我们明明用GBK的native编码,
让JVM拿iso8859读取,当然不对了!!

** 根本没有需要转码, 问题解决了!* 是的, 明白了原因所在, 把所有jsp文件头修改为: <%@ page language="java"
contentType="text/html; charset=UTF-8" pageEncoding="GBK" %>
不需要任何转码,最终输出的就是UTF-8, 没有任何问题. 而且这些文件采用native格式保存, 编辑最方便!

------------------------------
繁琐写了一大堆,说明了过程. 其中的教训是深刻的, 这就是我的标题中的:

 学艺要精,思考要慎

其实,在这个问题上折腾这么久, 只能怪自己学艺不精. pageEncoding是任何jsp的手册上都会说明的, 然而都被忽视了. 这个问题
我写这么多,让高人(甚至不需要高人, 只是认真读书看手册的人)见了, 只会见笑 --你们太烂了. 不过从google上看, 和我们一样烂的人太多 太多,
还有很多人在混乱编码的泥潭中挣扎.

拉起来就做,还没搞明白怎么回事,甚至"硬编码"解决,害人最深.

不幸的是,遇到了太多的项目, 太多的人, 他们宁可copy paste大量代码,花很多时间去debug, 费九牛二虎之力,把boss在心中诅咒100遍,
用不正确的方法去做事, 最终的结果可想而知.

以此为记, 希望今后我们项目中能不重复这样的错误, 也希望我们每个人,能多思考,用聪明而省力的方法去解决问题,而不是蛮干.

 发送彩信到 1297868.3. 9...@uublog.com 可直接评论该blog

老冒 <http://www.uuzone.com/uu/mao/> 发表于 2006-04-27 21:47
阅读<http://www.uuzone.com/blog/mao/98921.htm#>(
3001 <http://www.uuzone.com/blog/mao/98921.htm#> ) 评论(
10)<http://www.uuzone.com/blog/mao/98921.htm#comments> 引用(
0) <http://www.uuzone.com/blog/mao/98921.htm#TrackBack>
老冒观点<http://www.uuzone.com/blog/mao/278/>
所有人可见
      引用 http://www.uuzone.com/app/trackBack.do?type=blog&trackBackID=98921
 <http://www.uuzone.com/app/blogTopicPostLoad.do?type=1&trackBackID=98921>

    相关内容
更多.. <http://www.uuzone.com/blog/mao/278/>

   - 玩计算的家伙们都喜欢飞机? <http://www.uuzone.com/blog/mao/98723.htm>
   - 没有基本职业素养的秘书为何支持率高达八成? <http://www.uuzone.com/blog/mao/98899.htm>
   - 用心做事和用力做事 <http://www.uuzone.com/blog/mao/99722.htm>

  10评论 1
  [image: 汪洋里的海盗 优友:378 照片:450] <http://www.uuzone.com/uu/tommyhuang/>
 汪洋里的海盗 <http://www.uuzone.com/blog/tommyhuang/> 说:

不错

2006-04-27 23:06:36(5个月前) 评论.
  2
  [image: Caiwangqin 优友:104 照片:271] <http://www.uuzone.com/uu/uu_1115110/>
 Caiwangqin <http://www.uuzone.com/blog/uu_1115110/> 说:

这是JAVA的失败(当然更多的还是学艺不精),中国人大概是从1996年开始使用JAVA的,现在是2006年,十年过去了,JAVA还让人们在最基础的编码­工作上痛苦不堪。

JAVA is not fun for web UI.

2006-04-28 09:18:40(5个月前) 评论.
  3
  [image: Felix 优友:1 照片:0] <http://www.uuzone.com/uu/gzfelix/>
 Felix <http://www.uuzone.com/blog/gzfelix/> 说:

其实FileReader/FileWriter是根据默认的文件字符编码directive
file.encoding来编码读取/写入文件流的。你用的系统的字符集可能默认不是utf-8? (例如中文版的Windows or
LC_ALL&LANG设置为非UTF-8的Linux系统)所以有可能会出现类似问题。关键是要系统的file.encoding和文件的encoding相­对应,不然就会出问题。

JSP
Compiler一般是用InputStreamReader来读取文件的,指定了pageEncoding之后,也就指定了InputStream的char­set,所以pageEncoding指定的正是文件本身的encoding。

2006-04-28 09:52:20(5个月前) 评论.
  4
  [image: 老冒 优友:1051 照片:2156] <http://www.uuzone.com/uu/mao/>
 老冒 <http://www.uuzone.com/blog/mao/> 说:

Thanks felix !

2006-04-28 11:33:42(5个月前) 评论.
  5
  [image: Meteo 优友:0 照片:0] <http://www.uuzone.com/uu/uu_bccogll/>
 Meteo <http://www.uuzone.com/blog/uu_bccogll/> 说:

Not sure if know this site

http://www.web20workgroup.com/

It has all the latest info/news on web2.0

2006-04-28 14:43:52(5个月前) 评论.
  6
  [image: Meteo 优友:0 照片:0] <http://www.uuzone.com/uu/uu_bccogll/>
 Meteo <http://www.uuzone.com/blog/uu_bccogll/> 说:

+U +U , you guys are doing a good job

2006-04-28 14:47:49(5个月前) 评论.
  7
  [image: Meteo 优友:0 照片:0] <http://www.uuzone.com/uu/uu_bccogll/>
 Meteo <http://www.uuzone.com/blog/uu_bccogll/> 说:

btw, I didnt contact you recently because I thought you must be very very
busy. So please let me know when you are free.

2006-04-28 14:49:35(5个月前) 评论.
  8
  [image: 老冒 优友:1051 照片:2156] <http://www.uuzone.com/uu/mao/>
 老冒 <http://www.uuzone.com/blog/mao/> 说:

Sure I know that...

I am very busy these days...let‘s contact via email...

2006-04-28 15:02:13(5个月前) 评论.
  9
  [image: fireshort 优友:0 照片:0] <http://www.uuzone.com/uu/uu_bcpxtpz/>
 fireshort <http://www.uuzone.com/blog/uu_bcpxtpz/> 说:

"原来这些UTF-8的文件有一个所谓BOM <http://www.unicode.org.unicode/faq/utf_bom.html>头"
不 是UTF-8文件就有BOM头的,用editplus保存的UTF-8文件都没有BOM头。如果是在eclipse里面编辑jsp的话,根本不需要管
pageEncoding。我们在jsp里也用了include,没有设pageEncoding,在windows和linux下都好好的。

2006-10-19 10:18:43(1秒前) 评论.
编辑<http://www.uuzone.com/app/blogTopicReply.do?userID=mao&rid=134704>