字符集系列之四总结

来源:互联网 发布:淘宝商家放单群 编辑:程序博客网 时间:2024/06/02 10:41

一直对java中字符集的问题比较模糊,终于有了一个比较清晰的概念。

1、java虚拟机中默认都是Unicode的字符串,指的是java class存在的方式,包括javaclass存在的中文字符串,所以java的类可以跨平台。同样指的是虚拟机运行的方式,String对象本身是没有字符集概念的,它只是一个UniCode char的数组,而byte流是具有特定字符集特征的,不明确告诉jvm,就不能得到正确的解析。劉getBytes可以看作Unicode char到byte的转化。构建字符串的过程就可以看为byte到Unicode char的转化。

2、web容器httpRequest中的各种字符串的编码是由web容器实现的,根据RFC2616的规定,如果在HTTP请求中未指明字符集,就使用ISO8859_1编码,如:tomcat,但resin2.1.0是实现为本地编码。

其实是resin比其他服务多做了一步转化的工作,他将浏览器发出的ISO8859_1的字符流转变为本地字符集,然后通过httpRequest传给应用程序。

Java Servlets 2.3规范草案,其中在ServletRequest接口中新增了一个方法setCharacterEncoding(String enc),可以补上在HTTP请求中缺少的charset信息,可以在Servlet引擎内部实现,但是resin中不是这么实现的,因为通过getCharacterEncoding方法得到的值为Null;

3、jdbc:数据库与jdbc驱动程序之间传递的是ISO8859_1,对于应用程序来说,当进行存储的时候,正确的driver应该能够将内存以Unicode方式存储的字符串,转化为ISO8859_1,然后发送到数据库,数据库得到之后,会根据数据库字符集进行存储。

(昨天写的东西今天看了看,觉得还是不对,今天又做了一些修改,纠正了一些概念错误。谢谢class的意见。)

4、深入理解和猜想:我在想在网络中传递的其实就是字节流,恰好这个字节流与java对ISO8859_1字符的处理方式相近(一个字节匹配一个字符,我猜其他的00-ff的8位字符集都可以)。所以我们会认为存在着从UniCode到ISO8859_1的转换,其实在网络上传递的就是byte流。

这样,jdbc客户端发送数据时,采用getBytes()方式得到一个本地编码的byte流,这样传递到服务端,服务器端将这些字节用默认的数据库字符集整理组装起来,形成字符串。

http服务也是类似的效果,只是客户端环境是浏览器而已,发送时的编码也就时浏览器当时的编码了。